在C#中使用字符串和接口的字典

5

我有一个名为IObSrc的接口,我有一些实现该接口的类,如ObSrc1、ObScr2等。

Interface IObSrc
{
  string id;
}

我还有一个名为IDtSrc的接口,这个接口反过来由几个称为DtSrc1、DtSrc2的类实现。

Interface IDtSrc
{
  IObSrc getObject();
  Dictionary<string,IObSrc> getObjects();
}

当我从DtSrc1实现这个接口并返回ObSrc1时,没有问题,但是当我返回Dictionary<string,ObSrc1>Dictionary<string,ObSrc2>时,会出现类型不匹配的提示。

public class DtSrc : IDtSrc
{
  public Dictionary<string,IObSrc> getObjects()
  {
    Dictionary<string,ObSrc1> val1 = new ...'
    ...
    return val1;
  }

}

我可以帮你解决这个问题。

*编辑*

我还有一个问题,如果一个方法应该返回一个通用类型,但是实现可以有所变化,该怎么办。

例子:

interface IDtSrc<T> where T:IObSrc
{ 
  T ExecuteObject(string objId);
}

这将被用作

class DtSrc1 
{ 
  string ExecuteObject(string objId)
  {..}
}

并且。
class DtSrc2
{ 
 Dictionary<string,string> ExecuteObject(string objId)
 {..}
}

请提供正确的程序建议。

2
这些是否真正代表了你的接口/类名称?如果是这样,请为自己和其他开发人员着想,完全拼写出名称,例如 IDataSource。在当前的环境中没有必要使用缩写名称。 - Anthony Pegram
例如像 SqlCommand 和 DbCommand 这样的东西,@AnthonyPegram... - Yuriy Faktorovich
2
@YuriyFaktorovich:Sql是一个众所周知和被接受的缩写(就像Html)。Db可能会引起争议。但是省略所有元音字母就太邪恶了。 - ChrisWue
@ChrisWue 没有争议,我只是在说做这件事有原因。我也会详细说明的。 - Yuriy Faktorovich
2个回答

6
如果您声明一个类型为Dictionary<string,IObSrc>的字典,那么您不能以任何方式替换具有不同类型参数的字典,即使新的类型参数继承自原始类型。这就是为什么Dictionary<string, ObSrc1>Dictionary<string, ObSrc2>失败的原因。
您试图实现的目标称为类型协变,但在Dictionary<TKey, TValue>上不支持类型协变。类型协变只支持“只读”集合,即IEnumerable<T>
这可能看起来很傻,但考虑一下否则可能会发生什么:
Dictionary<string, IObSrc> dict = new Dictionary<string, ObSrc1>(); //illegal
dict.Add("X", new Obsrc2());

如果允许这样做,第二行代码将会编译成功,但在运行时会出现错误。

他将具体实现命名为 ObSrc1ObSrc2 而不是 IObSrc1 等等。阅读您的回答有点令人困惑。 - ChrisWue
@AdamRackis:感谢Adam和ChrisWue的解释。我计划尝试Yuriy提出的替代方案。 - Saravanan

6
您可以使用带有约束的泛型。
interface IDtSrc<T> where T:IObSrc
{
  IObSrc getObject();
  Dictionary<string,T> getObjects();
}

但是你实现的 IDtSrc 只能返回一种类型的 IObSrc

谢谢您的建议,它很好用。此外,我已经开始实现了,我还有一个问题,如果一个方法应该返回一个可以由实现进行变化的通用类型怎么办。例如:interface IDtSrc<T> where T:IObSrc{ T ExecuteObject(string objId);}。这将被用作类DtSrc1 { string ExecuteObject(string objId){..}}class DtSrc2{ Dictionary<string,string> ExecuteObject(string objId){..}}。请为此提供正确的程序建议。 - Saravanan

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