简体   繁体   English

覆盖 C# 中的通用约束

[英]Overriding generic constraint in C#

Apologies if this would be a better fit for the software engineering stack exchange, but as this is fairly language-specific, I believe I'm asking in the right place.抱歉,如果这更适合软件工程堆栈交换,但由于这是相当特定于语言的,我相信我在正确的地方问。

I have a project which involves converting a sizable codebase from Java to C#.我有一个项目涉及将相当大的代码库从 Java 转换为 C#。 The original Java project has an interface roughly equivalent to the following C# snippet.原始 Java 项目的接口大致相当于以下 C# 片段。

public interface IEntry<out T> where T : class, IEntry<T>{
  T SetName(string nameIn);

  string GetName();
}

It also contains a basic implementation of this interface.它还包含此接口的基本实现。

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;
  }
}

The problem arises in the class which holds entries of types implementing the IEntry<T> interface.问题出现在 class 中,它包含实现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
    }
  }
}

The indicated line gives me the below error on compilation.指示的行在编译时给了我以下错误。

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>'

I understand why I get this error, but I'm struggling to find a way around it.我理解为什么会出现此错误,但我正在努力寻找解决方法。 How could the above class be redesigned to allow access to the internal object field on types extending BaseEntry<T> ?如何重新设计上述 class 以允许访问扩展BaseEntry<T>类型的内部 object 字段?

So basically BaseEntry<T> is not equal to IEntry<T>所以基本上BaseEntry<T>不等于IEntry<T>

Analogy: You have a Mammal that implements ILegs , but not everything that has ILegs is a Mammal .类比:您有一个实现ILegsMammal ,但并非所有具有ILegs的都是Mammal

There are few fixes that you might want to look at, either pushing extraData back to IEntry<T> or as @ JeremyLakeman suggested, creating a separate generic or / non generic interface for IExtraData and constrain by that.您可能想要查看的修复程序很少,要么将extraData推回IEntry<T> ,要么正如@JeremyLakeman建议的那样,为IExtraData创建一个单独的通用或/非通用接口并受其约束。 The answer would depend on whether IEntry<T> always has extra data.答案取决于IEntry<T>是否总是有额外的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM