Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建接口子类的实例_C#_Windows - Fatal编程技术网

C# 创建接口子类的实例

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

我有接口和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>{}

只有当我将
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,我会尝试,但每次使用它时都需要转换为必要的类型?