c# - 如何将 polymorphism 与类型参数是 c# 中类型参数约束的子类型的泛型类型一起使用?

我有一个带有类型约束的泛型类型是一个基类。当我尝试使用类型约束的子类将 value 分配给此类型时,它不起作用。

我知道这样做的原因是因为编译器将它们视为两种完全不同的类型。

有解决办法吗?我唯一能想到的是创建一个通用类实现的接口,并通过任何方式公开类型。在下面的示例中,我可以让 barInstance 成为接口中定义的属性的实现。但这会产生一些样板。干杯!

public class Bar { }

public class SubclassOfBar : Bar { }

public class GenericClass<T> where T : Bar { 
    public T barInstance;
}

public class Example
{
    public void Test()
    {
        GenericClass<Bar> fooBar = new GenericClass<SubclassOfBar>(); // Does not compile
    }
}

使用界面解决方法:

public class Bar { }

public class SubclassOfBar : Bar { }

public class GenericClass<T> : IHaveBar where T : Bar
{
    public T barInstance;
    public Bar BarInstance => barInstance;
}

public class Example1
{
    public void Test()
    {
        IHaveBar fooBar = new GenericClass<SubclassOfBar>(); // Does Compile
    }

回答1

我明白你想做什么,但我不明白为什么。如果您希望变量 fooBar.BarInstance 仅引用 barInstance 属性而不是派生实例,则有几种方法。我也会扔掉那些明显的,以防万一:)

  1. 只需将泛型类型更改为 Bar。

    //Set both to the derived type.
     GenericClass<Bar> fooBar = new GenericClass<Bar>();
  2. 将两者都更改为派生类型并执行强制转换:

    public void Test()
     {
         GenericClass<SubclassOfBar> fooBar = new GenericClass<SubclassOfBar>();
         var instance = (Bar)fooBar.barInstance;
     }
  3. 您也可以使用您的解决方案,但不需要接口。

    public class Bar {
     }
    
     public class SubclassOfBar : Bar {
    
     }
    
    
     public class GenericClass<T> where T : Bar
     {
         private T barInstance;
         public Bar BarInstance => barInstance;
     }
    
     public class Example
     {
         public void Test()
         {
             var fooBar = new GenericClass<SubclassOfBar>();
             var instance = fooBar.BarInstance;
         }
     }
  4. 如果您想从上面的示例中删除“样板”代码,您可以将其全部放在一个抽象类中。 (这假设您将拥有多个这些泛型类)。

    public class Bar {
     }
    
     public class SubclassOfBar : Bar {
    
     }
    
     public abstract class AbstractGenericClass<T> where T : Bar
     {
         private T barInstance;
         public Bar BarInstance => barInstance;
     }
    
    
     public class GenericClass<T> : AbstractGenericClass<T> where T : Bar
     {
    
     }
    
     public class Example
     {
         public void Test()
         {
             var fooBar = new GenericClass<SubclassOfBar>();
             var instance = fooBar.BarInstance;
         }
     }

如果我需要澄清任何事情,请告诉我!

快乐编码!

回答2

如果你想在 Test 方法中做一些通用的东西,你也可以在方法中传递类型。代码会变成这样。

public void Test<T>() where T : Bar
{
    GenericClass<T> fooBar = new GenericClass<T>();
}

相似文章

随机推荐

最新文章