[英]Create instance of interface child class
I have interface and 3 classes that derives it, but how use 1 variable for each one type? 我有接口和3个派生它的类,但是如何为每个类型使用1个变量?
public interface IBuilder<T> where T: System.IConvertible{}
public class SimpleBuilder : IBuilder<SimpleCollagePatterns>{}
public class CreativeBuilder : IBuilder<CreativeCollagePatterns>{}
public class ShapeBuilder : IBuilder<ShapeCollagePatterns>{}
And I need create instance of class when it`s necessary 我需要在必要时创建类的实例
I have IBuilder<IConvertible> currentBuilder
variable, but I cannot create instance of any Builder
我有
IBuilder<IConvertible> currentBuilder
变量,但我无法创建任何Builder
实例
this.currentBuilder = new SimpleBuilder(); //Doesn`t work
Only if I change IBuilder<IConvertible> currentBuilder
to IBuilder<SimpleCollagePatterns> currentBuilder
or atother type I can create this type of Builder, but I need to have abulity create any type 只有当我将
IBuilder<IConvertible> currentBuilder
更改为IBuilder<SimpleCollagePatterns> currentBuilder
或其他类型时,我才能创建这种类型的Builder,但我需要abulity创建任何类型
I faced the same scenario. 我遇到了同样的情况。 But ended up to find there is no solution for this.
但最终发现没有解决方案。 It is not possible to create object of any type in run time.
在运行时无法创建任何类型的对象。 As you said, changing IBuilder currentBuilder to IBuilder currentBuilder is the only way to create object for SimpleBuilder type.
正如您所说,将IBuilder currentBuilder更改为IBuilder currentBuilder是为SimpleBuilder类型创建对象的唯一方法。 Similarly for other cases.
其他情况也是如此。
If you really want to use one variable for all scenarios, you can always define it as a simple object to hold on to the instance and use the IS operator to see which type it really is when necessary like this: 如果你真的想在所有场景中使用一个变量,你总是可以将它定义为一个简单的对象来保持实例并使用IS运算符来查看它在必要时的真实类型,如下所示:
if (this.currentBuilder is SimpleBuilder) { }
if(this.currentBuilder是SimpleBuilder){}
我相信你需要让你的IBuilder协变,请参阅https://msdn.microsoft.com/en-us/library/dd997386(v=vs.110).aspx
public interface IBuilder<out T>
What you want to read about is called covariance , which is denoted by keyword out
beside a generic type parameter in the interface declaration. 您想要阅读的内容称为协方差 ,它在接口声明中的泛型类型参数旁边用关键字
out
表示。
public interface IBuilder<out T> where T: System.IConvertible{}
This will allow you to declare a variable of type IBuilder<IConvertible>
and assign eg. 这将允许您声明
IBuilder<IConvertible>
类型的变量并分配例如。 SimpleBuilder
to it, you just need to be aware of what consequences applying covariance has, the most important being, in plain words, generic type can only be used as return type of the type members. SimpleBuilder
,它只需要知道应用协方差的后果,最重要的是,用简单的话来说,泛型类型只能用作类型成员的返回类型。
If you can't change the IBuilder
interface - there is no option to create a variable for all cases. 如果您无法更改
IBuilder
接口 - 则无法为所有情况创建变量。
For further info you can research SO, eg. 有关详细信息,您可以研究SO,例如。 Difference between Covariance & Contra-variance or read at the source, eg.
协方差和反方差之间的差异或从源头读取,例如。 https://msdn.microsoft.com/en-us/library/mt654055.aspx .
https://msdn.microsoft.com/en-us/library/mt654055.aspx 。
In particular if SimpleCollagePatterns
is used exclusivly by the class that implements that particular interface (In this case ShapeBuilder
), then you don't need covariance . 特别是如果
SimpleCollagePatterns
由实现特定接口的类(在本例中为ShapeBuilder
) ShapeBuilder
,那么您不需要协方差 。
There is a simple design pattern that relies on inheritance alone. 有一种简单的设计模式仅依赖于继承。
For example: 例如:
public interface IBuilder {
void Build();
}
public interface IBuilder<T> : IBuilder {
T BuildParameter {get;}
}
Note: The BuildParameter
corresponds to your BuildCollagePattern
注意:
BuildParameter
对应于您的BuildCollagePattern
Then you can implement the interface as such: 然后你可以这样实现接口:
public class SpecificBuilder : IBuilder<Int32> {
// The specific constructor
public SpecificBuilder(int param) { BuildParameter = param; }
// Implement from IBuilder
public void Build() {
System.Console.WriteLine("Building with Int32: " + BuildParameter);
}
// Implement from IBuilder<T>
public Int32 BuildParameter {get; private set;}
}
Then you can pass around any IBuilder<T>
as an IBuilder
然后你可以传递任何
IBuilder<T>
作为IBuilder
public class Program {
public static void Main() {
SpecificBuilder builder = new SpecificBuilder(42);
// SpecificBuilder implements IBuilder<Int32>
// Build accepts any IBuilder
// So this is legal:
Build(builder);
}
//
// Note this method accepts anything that inherits from IBuilder
//
public static void Build(IBuilder builder) {
builder.Build();
// If you'd need access to the BuildParameter of IBuilder<T>
// then this pattern fails you here.
// Unless of course you want to check for types and cast
}
}
As noted before: Once you need access to the generic type outside of the class thats implementing the IBuilder<T>
you'd need to start differentiating types and cast them accordingly. 如前所述:一旦您需要访问实现
IBuilder<T>
的类之外的泛型类型,您需要开始区分类型并相应地转换它们。 Not so elegant. 不那么优雅。
But you can design lot's of stuff this way and maintain extensibility. 但是你可以用这种方式设计很多东西并保持可扩展性。 I bring this up, as I have used this pattern to implement image filters myself and your
BuildCollagePattern
might be very much realizable with this design pattern. 我提出这个问题,因为我已经使用这种模式自己实现了图像过滤器,并且使用这种设计模式可以很好地实现
BuildCollagePattern
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.