我有一个带有两个通用方法签名的非泛型接口。
interface IDataContainer
{
T GetValue<T>();
void SetValue<T>(T value);
}
然后我有一个实现IDataContainer
的泛型类public class DataContainer<T>: IDataContainer
{
private T _value;
#region IDataContainer Members
public T GetValue<T>()
{
return _value;
}
public void SetValue<T>(T value)
{
_value = value;
}
#endregion
}
我收到的错误是无法在已实现的GetValue和SetValue方法上将类型T隐式转换为T.
有没有办法解决这个问题?平等的某种类型约束?还有更好的方法吗?
我知道我可以通过使它成为IDataContainer<T>
来使IDataContainer变得通用,但是当T不总是相同的类型时,我就没有IDataContainer的列表。
答案 0 :(得分:1)
您的问题是编译器看到两种不同的类型。 IDataContainer范围内的T与泛型方法范围内的T不同,因此编译器会抱怨。
因为您的容器包含T的实例,我认为您的接口也应该具有类型参数T(不仅仅是方法范围泛型参数)。
您当前的界面实际承诺(记住,界面是合约),能够为任何T提供T值 - 肯定不是您想要的?
答案 1 :(得分:1)
您可以在通用界面中很好地捕获代码的意图:
interface IDataContainer<T> {
T GetValue();
void SetValue(T value);
}
那你为什么要使用泛型方法的非通用接口?
泛型方法的问题是类型参数不是相同的,尽管它们具有相同的名称。
要获得T不相同时的数据容器列表,只需为通用接口设置非通用的基本接口:
interface IDataContainer { }
interface IDataContainer<T> : IDataContainer {
...
}
然后您可以拥有非通用数据容器的列表。
答案 2 :(得分:0)
这两种方法意味着两种不同的东西。在IDataContainer中,指定泛型方法。这可以用任何类型调用。在DataContainer
中,指定采用类中指定的特定类型参数的方法。 IDataContainer
不满足DataContainer
的合同。您应该更改IDataContainer
,以便它是通用的。
为了更清楚,请单独考虑IDataContainer
。无论getContainer()
IDataContainer ctr = getContainer();
String x = ctr.getValue<String>();
但是,如果getContainer看起来如下所示,那么如果您拥有的内容合法,那么该代码会明显破解:
public IDataContainer getContainer() {
return new DataContainer<Foo>();
}
您遇到的根本问题是,如果您有不同类型的DataContainer,那么这些DataContainer的合同就完全不同了。 DataContainer<Foo>
有一个GetValue
可以为您提供Foo
,而DataContainer<Bar>
有一个GetValue
会为您提供Bar
。如果有一个Foo和Bar的超类,那么你可以使用它,否则,你将要进行投射,因为如果你把它们一起扔进一个列表中就不能保证类型安全。