[英]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 :)
我也会扔掉那些明显的,以防万一:)
Simply change the generic types to Bar.只需将泛型类型更改为 Bar。
//Set both to the derived type. GenericClass<Bar> fooBar = new GenericClass<Bar>();
Change both to the derived type and perform a cast:将两者都更改为派生类型并执行强制转换:
public void Test() { GenericClass<SubclassOfBar> fooBar = new GenericClass<SubclassOfBar>(); var instance = (Bar)fooBar.barInstance; }
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; } }
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.