【问题标题】:using generic class in Dictionary C#在 Dictionary C# 中使用泛型类
【发布时间】:2014-05-14 15:06:34
【问题描述】:

我需要实现一个集合(例如,SpecCollection),它应该包含KEYVALUE。键应该是复合键。请看简短的实现:

public class CompositeKey<TId, TName>
{
    private TId _id;
    private TName _name;

    public TId Id { get; set; }
    public TName Name { get; set; }
}

我应该只通过以下方式初始化我的集合:

SpecialCollection<CompositeKey<string, int>, DateTime> e = new 
    SpecialCollection<CompositeKey<string, int>, DateTime>();

或者像这样:

SpecialCollection<CompositeKey<DateTime, int>, SomeClass> e = new 
    SpecialCollection<CompositeKey<DateTime, int>, SomeClass>();

如果可能,请告诉我如何声明我的收藏?

我找到了以下方法:

public class SpecialCollection<TId, TName, TValue> 
    : Dictionary<CompositeKey<TId, TName>, TValue> 
{
    private Dictionary<CompositeKey<TId, TName>, TValue> _baseDictionary = new 
        Dictionary<CompositeKey<TId, TName>, TValue>();
}

但在这种情况下,我只能像这样初始化集合对象:

SpecialCollection<DateTime, int, string> col = 
    new SpecialCollection<DateTime, int, string>();

您对如何声明集合有任何想法吗?

谢谢!

【问题讨论】:

  • 我也是?你怎么了?你想要什么?
  • OP 正在寻找一种在不指定类型的情况下使用CompositeKey&lt;&gt; 作为SpecialCollection&lt;&gt; 的类型参数的方法。
  • 我需要实现一个只能像这样初始化的集合:SpecialCollection&lt;CompositeKey&lt;AnyType, AnyType&gt;, AnyType&gt; e = new SpecialCollection&lt;CompositeKey&lt;AnyType, AnyType&gt;, AnyType&gt;(); 集合的键应该是集合的键应该是CompositeKey
  • 鲍勃森,你说的对!

标签: c# generics collections


【解决方案1】:

没有办法完全按照您的意愿行事 - .NET 编译器不能部分直观地为泛型提供类型参数。这让您有三个选择。

  1. 什么都不做。你现在的工作方式是实现这样的标准的方式。您会自动获得所需的密钥类型 (CompositeKey&lt;Tid, TName&gt;)。

  2. 放弃CompositeKey&lt;&gt;的类型。在这种情况下,您接受任何 CompositeKey 作为 TKey 值。为此,您需要CompositeKey 的非泛型基类或ICompositeKey 接口。但是,您将无法访问 Tid 和 TNameinsideSpecialCollectioN` 的类型,因为您没有指定它可以使用的任何类型。

    public class SpecialCollection<TKey, TValue> 
        : Dictionary<TKey, TValue> where TKey : CompositeKey
    {
        private Dictionary<TKey, TValue> _baseDictionary = new 
            Dictionary<TKey, TValue>();
    }
    
  3. 指定四个类型参数。这样,你强制第一个类型为CompositeKey&lt;Tid, TName&gt;SpecialCollection&lt;&gt;会知道它的类型是。另一方面,您必须指定所有四个,因为 C# 不能进行部分泛型类型推断。 (即全有或全无)。请注意,您可以将顺序更改为对您最有意义的顺序。

    public class SpecialCollection<TKey, TValue, Tid, TName> 
        : Dictionary<TKey, TValue> where TKey : CompositeKey<Tid, TName>
    {
        private Dictionary<TKey, TValue> _baseDictionary = new 
            Dictionary<TKey, TValue>();
    }
    

【讨论】:

    【解决方案2】:

    也许你正在寻找这样的东西:

    public class SpecialCollection<TKey, TValue> : Dictionary<TKey, TValue>
        where TKey : CompositKey
    {
    }
    
    public abstract class CompositeKey
    {
        protected CompositeKey(object id, object name)
        {
            Id = id;
            Name = name;
        }
    
        public object Id { get; private set; }
    
        public object Name { get; private set; }
    }
    
    public class CompositeKey<TId, TName> : CompositeKey
    {
        public CompositeKey(TId id, TName name)
            : base(id, name) { }
    
        public new TId Id
        {
            get { return (TId)base.Id; }
        }
    
        public new TName Name
        {
            get { return (TName)base.Name; }
        }
    }
    

    抽象非泛型 CompositeKey 类使您可以有限地访问 SpecialCollection 类中的 IdName 属性。

    但我认为你应该考虑你的第一个想法,因为这样你就有了IdName 上可能需要的类型安全性。

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多