如何编写一个函数来获取带有索引运算符的任何对象

本文关键字:索引 运算符 对象 任何 获取 何编写 函数 一个 | 更新日期: 2023-09-27 18:09:39

我想我以前在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中的结果转换为哈希表,但我预计很快就会需要更多的源类型。

如何编写一个函数来获取带有索引运算符的任何对象

您可以使用一个接口:

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

您能添加一个约束来指定类型参数是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公开了这一点。

C#中没有运算符的泛型类型约束-这是C#中泛型的限制之一。

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

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