代码之家  ›  专栏  ›  技术社区  ›  benPearce

通用接口列表

  •  6
  • benPearce  · 技术社区  · 15 年前

    如果我有一个带有两个实现类的通用接口,例如:

    public interface IDataElement<T>
    {
        int DataElement { get; set; }
        T Value { get; set; }
    }
    
    public class IntegerDataElement : IDataElement<int>
    {
        public int DataElement { get; set; }
        public int Value { get; set; }
    }
    
    public class StringDataElement : IDataElement<String>
    {
        public int DataElement { get; set; }
        public String Value { get; set; }
    }
    

    是否可以传递不同类型的实现类集合,而不必使用作为对象传递。

    似乎无法将返回值定义为

    public IDataElement<T>[] GetData()
    

    public IDataElement<object>[] GetData() 
    

    有什么建议吗?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Thomas Levesque    15 年前

    您当然可以声明:

    public IDataElement<T>[] GetData<T>()
    

    public IDataElement<object>[] GetData()
    
    • 尽管后者可能不是您所追求的(即使在C 4中,您的接口也不会是变量 T 在输入和输出位置;即使它是变量,您也不能将该变量用于值类型)。前者将要求调用者指定 <T> ,例如

      foo.GetData<string>();

    你可以吗?

    无法表达“一个对象集合,每个对象集合实现 IDataElement<T> 对于一个不同的t“,除非你也给它一个非能量的基类,在那里你可以使用 IList<IDataElement> . 在这种情况下,非能量的 IDataElement 可能有 DataElement 属性,离开 Value 通用接口中的属性:

    public interface IDataElement
    {
        int DataElement { get; set; }
    }
    
    public interface IDataElement<T> : IDataElement
    {
        T Value { get; set; }
    }
    

    这对你的特殊情况有用吗?

    不清楚您希望如何在不知道数据元素类型的情况下使用它们的集合…如果上面的内容对您没有帮助,也许您可以多说一些您希望如何处理这些收藏。

        2
  •  3
  •   Lee    15 年前

    不,您不能这样做-唯一的选项是使用非通用接口:

    public interface IDataElement
    {
        int DataElement { get; set; }
        object Value { get; set; }
    }
    

    或者,创建一个包装器,并将其传递给知道所需类型的方法:

    public class DataElementBag
    {
        private IDictionary<Type, List<object>> _elements;
        ...
        public void Add<T>(IDataElement<T> de)
        {
            Type t = typeof(T);
            if(!this._elements.ContainsKey(t))
            {
                this._elements[t] = new List<object>();
            }
    
            this._elements[t].Add(de);
        }
    
        public void IEnumerable<IDataElement<T>> GetElementsByType<T>()
        {
            Type t = typeof(T);
            return this._elements.ContainsKey(t)
                ? this._elements[t].Cast<IDataElement<T>>()
                : Enumerable.Empty<T>();
        }
    }