how to write a function to take any object with an index operator

余生颓废 提交于 2019-12-04 06:53:04

问题


I think I have asked this in the context of C++ (Can't find it in my question history!!) in the past and the solution was to use a template function. As C++ template resolve at compile time, it works. But for C#, it doesn't.

public Hashtable ConvertToHashtable<T>(T source) where T has an index operator
{
    Hashtable table = new Hashtable();
    table["apple"] = source["apple"];

    return table;
}

One usage at the moment is to convert the result in OleDbReader to hashtable, but I am forseeing the need for more source types soon.


回答1:


There are no generic type constraints for operators in C# - it is one of the limitations of generics in C#.




回答2:


You can use an interface:

public interface IIndexable<T> {
    T this[int index] { get; set; }
    T this[string key] { get; set; }
}

and your method will be seen as below:

public Hashtable ConvertToHashtable<T>(T source) 
    where T : IIndexable<T> {

    Hashtable table = new Hashtable();
    table["apple"] = source["apple"];
    return table;

}

A simple source is:

public class Source : IIndexable<Source> {

    public Source this[int index] {
        get {
            // TODO: Implement 
        }
        set {
            // TODO: Implement 
        }
    }

    public Source this[string key] {
        get {
            // TODO: Implement 
        }
        set {
            // TODO: Implement 
        }
    }
}

A simple consumer is:

public class Consumer{

    public void Test(){
        var source = new Source();
        var hashtable = ConvertToHashtable(source);
        // you haven't to write: var hashtable = ConvertToHashtable<Source>(source);
    }

}



回答3:


Could you add a constraint to specify that the type parameter was an IList?

public Hashtable ConvertToHashtable<T>(T source) where T : IList
{
    Hashtable table = new Hashtable();
    table["apple"] = source["apple"];

    return table;
}

The Item property this[int index] is not an operator, its a property member of the containing type. IList exposes this.




回答4:


If runtime checks are good enough, you could use reflection as one of the commentator suggested as follows:

if (typeof (T).GetProperties().Any(property => property.Name.Equals("Item")))


来源:https://stackoverflow.com/questions/7544227/how-to-write-a-function-to-take-any-object-with-an-index-operator

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