2

I have a method, accepting a Hashtable (yes I know, it's outdated..) as argument:

public static LuaTable HashtableToLuatable(Hashtable t, int depth = 1)

This works correctly.

Now I'd like to accept an ArrayList as first parameter as well, so you can let 't' have the value of both a Hashtable and an ArrayList. Currently I have copy-pasted the method two times, like this:

public static LuaTable ArraylistToLuatable(ArrayList t, int depth = 1)

The rest is exactly the same.

I think there's a way to merge this.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tgys
  • 612
  • 1
  • 11
  • 21
  • It sounds like the behavior would be quite different. One is a key->value mapping. The other is a list. I would also encourage you to use generics where possible, even if it's only `Dictionary`. – Matthew Flaschen Apr 12 '12 at 17:40
  • The problem is mainly that the DLL I'm using is outdated itself, so it throws up such problems. --- foreach (DictionaryEntry bit in t) -- works anyway. – Tgys Apr 12 '12 at 17:42

5 Answers5

10

Both classes implement the ICollection interface, so if your 'common code' will work against the definition of the ICollection interface, you could use that for your parameter type.

medkg15
  • 1,565
  • 15
  • 13
2

You have shown an example of method overloading, and so far what you are doing works within the framework of C#.

The question is, what what must the method do with the passed-in value. There must be some means of treating them as "equivalent". One way to do that is if both types implement the same interface.

ArrayList implements: IList, ICollection, IEnumerable

Hashtable implements: IDictionary, ICollection, IEnumerable

If the code inside your method body just treats the first argument like a collection, you can change the method signature to:

public static LuaTable HashtableToLuatable(ICollection t, int depth = 1)

If your implementation does not use or require everything in ICollection, you could instead specify

public static LuaTable HashtableToLuatable(IEnumerable t, int depth = 1)

More objects implement IEnumerable than ICollection, so using IEnumerable (if possible) will allow for greater flexibility down the road to pass in a different type of object.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • Useful information over there. Thanks for explaining how to reproduce such a solution, will be very handy in many other cases. – Tgys Apr 12 '12 at 17:54
2

Both types implement IEnumerable and ICollection, so rewrite your method signature to use one of those instead:

public static LuaTable EnumerableToLuaTable(IEnumerable t, int depth = 1)

or

public static LuaTable CollectionToLuaTable(ICollection t, int depth = 1)

I'd prefer the IEnumerable option over ICollection, if you don't need anything in ICollection.

Steve Czetty
  • 6,147
  • 9
  • 39
  • 48
  • Why would IEnumerable be better then ICollection? – Tgys Apr 12 '12 at 18:04
  • IEnumerable is more abstract, meaning your method can be used with more types in the future without modification, should you find the need. In this case, it probably doesn't matter too much. – Steve Czetty Apr 12 '12 at 18:20
1

Both of these (terribly outdated) types implement two common interfaces, namely; IEnumerable and ICollection. So, you can set a generic constraint based on on of those interfaces.

static void ArraylistToLuatable<T>( T collection ) where T : IEnumerable
{
    foreach( var item in collection )
    {
        // do something
    }
}

Of course, this still sucks, because item is going to be of type object, which will work better for your ArrayList argument than your HashTable argument as, under the covers, you have to deal with a DictionaryEntry somehow, which means you have to check its type in the method and cast your item appropriately.

Are you sure you can't use a more up to date generic collection type? Would it be possible to wrap them in a generic collection as you get them from your DLL? I suppose it depends on how much of this sort of thing is needed on your end. If it's just one or two methods it's probably fine this way.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
0

You could try generics, if that works for you..

public static LuaTable <T> HashtableToLuatable(T t, int depth = 1) where T : ICollection

You may also derive your own datatypes if the above does not fit your case..

Robin Maben
  • 22,194
  • 16
  • 64
  • 99