简体   繁体   English

如何将多态性与泛型类型一起使用,该泛型类型的类型参数是 C# 中类型参数约束的子类型?

[英]How do I use polymorphism with a generic type who's type argument is a child of the type parameter constraint in c#?

I have a genericType whos type constraint is a base class.我有一个 genericType,其类型约束是一个基类。 When I try to assign a value to this type, using a subclass of the type constraint, it doesn't work.当我尝试使用类型约束的子类为这种类型分配值时,它不起作用。

I understand that the reasoning for this is because compiler sees these as two completely different types.我知道这样做的原因是因为编译器将它们视为两种完全不同的类型。

Is there a work around for this?有解决办法吗? The only thing I can think of is to create an interface which the Generic Class implements an exposes the type through by whatever means.我唯一能想到的是创建一个通用类实现的接口,并通过任何方式公开类型。 In the example below I could just make the barInstance the implementation of a property defined in the interface.在下面的示例中,我可以让 barInstance 成为接口中定义的属性的实现。 But this creates some boiler plate.但这会产生一些样板。 Cheers!干杯!

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

Work Around with interface:使用界面解决方法:

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
    }

I understand what you're trying to do, but I do not understand why.我明白你想做什么,但我不明白为什么。 If you want your variable fooBar.BarInstance to only have reference of the barInstance properties on not the derived instance, there are a few ways.如果您希望变量 fooBar.BarInstance 仅引用 barInstance 属性而不是派生实例,则有几种方法。 I'll throw down the obvious ones as well, just incase :)我也会扔掉那些明显的,以防万一:)

  1. Simply change the generic types to Bar.只需将泛型类型更改为 Bar。

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

     public void Test() { GenericClass<SubclassOfBar> fooBar = new GenericClass<SubclassOfBar>(); var instance = (Bar)fooBar.barInstance; }
  3. You could also go with your solution, but there is no need for an interface.您也可以使用您的解决方案,但不需要界面。

     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. If you would like to remove the "boiler plate" code from the example above, you could put it all in an abstract class.如果您想从上面的示例中删除“样板”代码,您可以将其全部放在一个抽象类中。 (This assumes you are going to have more than one of these generic classes). (这假设您将拥有多个这些通用类)。

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

Let me know if I need to clarify anything!如果我需要澄清任何事情,请告诉我!

Happy coding!快乐编码!

If you want to do some generic stuff in the Test method, you could pass in the type in the method as well.如果你想在 Test 方法中做一些通用的东西,你也可以在方法中传递类型。 The code would become like this.代码会变成这样。

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

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

相关问题 如何将接口用作 C# 泛型类型约束? - How can I use interface as a C# generic type constraint? 如何将 `where T : U` 泛型类型参数约束从 C# 转换为 F#? - How do I translate a `where T : U` generic type parameter constraint from C# to F#? 如何约束通用类型参数以仅接受C#中的可为空的值类型? - How do I constraint a generic type parameter to only accept nullable value types in C#? 如何使用泛型类型的类型参数作为方法参数的类型? - How can I use a generic type's type argument as the type of a method parameter? C#泛型如何获取没有对象类型作为参数的泛型方法的参数类型? - C# Generics How Can I get the type passed as an argument for a generic method with no object type as a parameter? C#是具有通用类型约束的通用类型 - C# is generic type with generic type constraint 具有泛型类型约束的 C# 多态性 - C# Polymorphism with generic type constraints 具有泛型类型和列表的C#多态 - C# polymorphism with generic type and list 在C#中使用通用类型作为参数 - use a generic type as parameter in C# 通用类型约束:如何创建 C# 文档中描述的 class 的实例 - Generic type constraint: How do I create an instance of the class described in this C# documentation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM