我可以为此[]属性使用通用类型吗?

7

我有一个DICOM字典,其中包含一组从DataElement派生出来的对象。 该字典的键是int类型,属性是DataElement。 我的DICOM字典包含一个this[]属性,我可以通过它访问DataElement,例如:

public class DicomDictionary
{
  Dictionary<int, DataElement> myElements = new Dictionary<int, DataElement>();
  .
  .
  public DataElement this[int DataElementTag]
  {
    get
    {
      return myElements[int];
    }
  }
}

目前的问题是,我有不同的DataElement类型,都派生自DataElement,例如DataElementSQ、DataElementOB等。现在我想做的是让C#编写变得更加容易:

 public T this<T>[int DataElementTag] where T : DataElement
 {
   get
   {
      return myElements[int];
   }
 }

但这实际上是不可能的。我有什么遗漏了吗?当然,我可以使用Getter方法来实现,但这种方式更好。


1
无法定义泛型属性(包括索引器)https://dev59.com/UXRB5IYBdhLWcg3w1Kr0 - Dean Chalk
无论你是否相信,依我看,你所建议的做法会让使用和阅读变得混乱。 - Marc
4个回答

4

最好的选择是使用通用方法(而不是索引器),或者使您的类成为通用类(在这种情况下,索引器将与类通用类型相关联)。C#不允许您描述的通用索引器。


嗨,里德,你说得对,我可以创建一个通用类,但我试图不要像这样做,因为目前它在没有通用类的情况下工作。 - msedi
@msedi:从您展示的内容来看,问题的一部分是Dictionary可能包含多种类型 - 即使它能工作,您也无法保证当前代码的类型安全性。话虽如此,C#规范并不支持它... - Reed Copsey
@msedi:如果类本身不知道索引器应该返回什么类型,那么谁知道呢?调用方知道类型而不知道类是一个糟糕的设计。那么你的用例到底是什么呢?你是否将拥有只包含单个子类型实例的此类实例?或者你希望混合使用子类型,并信任调用代码知道它所获取的类型?目前你的设计似乎有些奇怪... - Chris

2

这对您来说是一个问题吗?

public class DicomDictionary<TElement> 
{
        Dictionary<int, TElement> myElements = new Dictionary<int, TElement>();
        public TElement this[int DataElementTag]   
        {     
              get     
              {       
                 return myElements[int];     
              }   
        } 
}

嗨,sllev,也许我得考虑一下。我看到没有其他办法,也许我应该按照你的建议去做。 - msedi

2
为什么不使用一个真正的通用方法 GetDataElement<T> where T : DataElement 呢?C# 不支持通用索引器。为什么您认为在这种情况下,索引器比方法更好呢?

嗨Danny,这就是我期望的。有一个getter方法的问题,事实上我内部有这样的方法,会使代码变得更加难以阅读,而不是像这个简短的方法一样。当然,如果我必须强制转换它,那么情况也不同。这就是为什么我在寻找这样的东西。目前我可以接受它,但这个问题浮现在我的脑海中。 - msedi

0

所有答案的附加内容如下:

public class Acessor<TKey, TValue>
    where TKey : IComparable
    where TValue : class
{
    Dictionary<TKey, TValue> myElements = new Dictionary<TKey, TValue>();

    public TValue this[TKey key]
    {
        get
        {
            return myElements[key];
        }
        set
        {
            myElements.Add(key, value);
        }
    }
}

或者不改变类的签名:

 public class Acessor
{
    Dictionary<string, object> myElements = new Dictionary<string, object>();

    public object this[string key]
    {
        get
        {
            return myElements[key];
        }
        set
        {
            myElements.Add(key, value);
        }
    }
}

创建一个方法来解析泛型类型:
public T Get<T>(string key)
        where T : class
    {
        return (T)Convert.ChangeType(acessor[key], typeof(T));
    }

你在第二段代码片段中为什么使用 object?这似乎比使用 DataElement 原来的方式更糟糕... - Chris
我使用了 object 来进行通用的使用。 - Houston da Paz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接