【问题标题】:how to write a function to take any object with an index operator如何编写函数以使用索引运算符获取任何对象
【发布时间】:2011-11-24 13:06:06
【问题描述】:

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

【问题讨论】:

  • 你必须为此使用反射。
  • C# 中的运算符没有泛型类型约束 - 这是 C# 中泛型的限制之一。
  • @Oded 你能写下你的评论作为答案吗?谢谢。

标签: c# generics indexer


【解决方案1】:

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

【讨论】:

    【解决方案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);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 这对于 source["apple"] 有效的东西没有意义。
        猜你喜欢
        • 2011-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        相关资源
        最近更新 更多