How to let a method accept two types of data as argument?

浪子不回头ぞ 提交于 2020-01-05 04:26:07

问题


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.


回答1:


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.




回答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.




回答3:


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.




回答4:


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.




回答5:


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..



来源:https://stackoverflow.com/questions/10128823/how-to-let-a-method-accept-two-types-of-data-as-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!