C# 创建接口子类的实例
我有接口和3个派生它的类,但是如何为每种类型使用1个变量呢C# 创建接口子类的实例,c#,windows,C#,Windows,我有接口和3个派生它的类,但是如何为每种类型使用1个变量呢 public interface IBuilder<T> where T: System.IConvertible{} public class SimpleBuilder : IBuilder<SimpleCollagePatterns>{} public class CreativeBuilder : IBuilder<CreativeCollagePatterns>{}
public interface IBuilder<T> where T: System.IConvertible{}
public class SimpleBuilder : IBuilder<SimpleCollagePatterns>{}
public class CreativeBuilder : IBuilder<CreativeCollagePatterns>{}
public class ShapeBuilder : IBuilder<ShapeCollagePatterns>{}
只有当我将
IBILDER currentBuilder
更改为IBILDER currentBuilder
或其他类型时,我才能创建这种类型的生成器,但我需要创建任何类型的生成器,我面临着相同的情况。但最终发现没有解决办法。无法在运行时创建任何类型的对象。正如您所说,将IBuilder currentBuilder更改为IBuilder currentBuilder是为SimpleBuilder类型创建对象的唯一方法。类似地,对于其他情况。如果您真的想在所有情况下使用一个变量,您可以始终将其定义为一个简单的对象,以保留实例,并在必要时使用IS运算符查看它真正是哪种类型,如下所示:
if(this.currentBuilder是SimpleBuilder)
{
}
我相信你需要让你的iBulder协变,明白吗
public interface IBuilder
您想了解的内容称为协方差,它由接口声明中的泛型类型参数旁边的关键字out
表示
this.currentBuilder = new SimpleBuilder(); //Doesn`t work
public interface IBuilder<out T> where T: System.IConvertible{}
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
}
}
公共接口IBuilder,其中T:System.IConvertible{}
这将允许您声明一个类型为IBuilder
的变量,并为其赋值,例如SimpleBuilder
,您只需要知道应用协方差会产生什么后果,最重要的是,简单地说,泛型类型只能用作类型成员的返回类型
如果您无法更改iBilder
接口,则没有为所有情况创建变量的选项
如果您不需要对泛型类型的公共访问,您可以进行进一步的研究,例如,或在源代码处阅读,例如…
特别是,如果实现该特定接口的类(在本例中为ShapeBuilder
)独占使用SimpleCollagePatterns
,则不需要协方差
有一种简单的设计模式仅依赖于继承
例如:
public interface IBuilder {
void Build();
}
public interface IBuilder<T> : IBuilder {
T BuildParameter {get;}
}
然后,您可以将任何iBilder
作为iBilder
this.currentBuilder = new SimpleBuilder(); //Doesn`t work
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
}
}
公共类程序{
公共静态void Main(){
SpecificBuilder=新SpecificBuilder(42);
//SpecificBuilder实现IBuilder
//Build接受任何IBuilder
//所以这是合法的:
建造商;
}
//
//注意:此方法接受从IBuilder继承的任何内容
//
公共静态无效生成(IBuilder builder){
builder.Build();
//如果需要访问IBuilder的BuildParameter
//那么这个模式在这里不适用。
//当然,除非你想检查类型和类型转换
}
}
如前所述:一旦需要访问实现IBuilder
的类之外的泛型类型,就需要开始区分类型并相应地强制转换它们。不那么优雅
但是你可以用这种方式设计很多东西并保持可扩展性。我提出了这个问题,因为我自己使用了这个模式来实现图像过滤器,而你的
BuildCollagePattern
可能很容易用这个设计模式实现。我还有一个方法,它使用了currentBuilder的dynamic
类型,但不是很好。这不好。因此,解决方案是为每种类型都有一个单独的对象。接口不是类,因此不能创建它们的实例。创建实例的唯一方法是按照您选择的方式,即定义实现接口的类,例如SimpleCollagePatterns。此外,接口不包含任何执行特定操作的代码,那么为什么要创建它们的实例呢?为什么不将IBuilder更改为父类呢?您面临的问题是,您有I
和I
(即,相同的泛型接口使用了两次不同的泛型参数),并且T1
和T2
之间存在继承层次结构。问题是I
和I
之间没有继承层次结构。根据继承的方式,可以使用协方差和逆变来处理这个问题,但这对类型的使用有非常具体的限制,可能不是您想要的。简言之,这是不可能做到的。但我不能改变它。我需要更改类型为什么不能更改currentBuilder的声明?这不是你自己的代码吗?因此,将IBuilder currentBuilder替换为object currentBuilder。如何执行此操作?将IBuilder currentBuilder替换为object currentBuilderhmm,我会尝试,但每次使用它时都需要转换为必要的类型?