如何编写一个函数来使用索引运算符获取任何对象

时间:2011-09-25 07:29:56

标签: c# generics indexer

我想我过去在C ++(在我的问题历史记录中找不到它)的上下文中问过这个问题,解决方法是使用模板函数。当C ++模板在编译时解析时,它可以工作。但是对于C#,它没有。

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

    return table;
}

目前的一个用法是将OleDbReader中的结果转换为哈希表,但我很快就会想到更多源类型。

4 个答案:

答案 0 :(得分:2)

您可以使用界面:

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

您的方法如下:

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

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

}

一个简单的来源是:

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

一个简单的消费者是:

public class Consumer{

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

}

答案 1 :(得分:1)

是否可以添加约束以指定类型参数为IList

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

    return table;
}

Item属性this[int index]不是运算符,它是包含类型的属性成员。 IList暴露了这一点。

答案 2 :(得分:0)

如果运行时检查足够好,您可以使用反射作为评论员之一,如下所示:

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

答案 3 :(得分:0)

C#中的运算符没有通用type constraints - 这是C#中泛型的限制之一。