如果这更适合软件工程堆栈交换,我深表歉意,但由于这是相当特定于语言的,我相信我是在正确的地方提问。
我有一个项目,涉及将相当大的代码库从 Java 转换为 C#。原始 Java 项目的接口大致相当于以下 C# 代码段。
public interface IEntry<out T> where T : class, IEntry<T>{
T SetName(string nameIn);
string GetName();
}
它还包含此接口的基本实现。
public abstract class BaseEntry<T> : IEntry<T> where T : BaseEntry<T>{
private string name;
internal object extraData;
public T SetName(string nameIn){
name = nameIn;
return (T)this;
}
public string GetName(){
return name;
}
}
问题出现在包含实现 IEntry<T>
接口的类型条目的类中。
public class ObjectHolder<T> where T : class, IEntry<T>{
private readonly List<T> entries;
private readonly bool canGetExtraData;
public ObjectHolder(){
//HasGenericBaseType simply checks if the first type implements the second type
canGetExtraData = HasGenericBaseType(typeof(T), typeof(BaseEntry<>));
}
public void Add(T entry){
entries.Add(entry);
}
public void DoSomething(int index){
if(!canGetExtraData){
T entry = entries[index];
object extraData = ((BaseEntry<T>)entry).extraData; <-- This cast fails on compilation
//Something gets done with the extraData object
}
}
}
指示的行在编译时给了我以下错误。
error CS0314: The type `T' cannot be used as type parameter `T' in the generic type or method `BaseEntry<T>'. There is no boxing or type parameter conversion from `T' to `BaseEntry<T>'
我明白为什么会出现此错误,但我正在努力寻找解决方法。如何重新设计上述类以允许访问扩展 BaseEntry<T>
的类型的内部对象字段?
答案 0 :(得分:1)
所以基本上BaseEntry<T>
不等于IEntry<T>
类比:您有一个实现 Mammal
的 ILegs
,但并非所有具有 ILegs
的都是 Mammal
。
您可能想要查看的修复程序很少,要么将 extraData
推回 IEntry<T>
,要么按照 @JeremyLakeman 的建议,创建一个单独的通用或/非通用 IExtraData
的接口并受其约束。答案取决于 IEntry<T>
是否总是有额外数据。