创建接口子类的实例

时间:2016-11-23 09:17:46

标签: c# windows

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

我需要在必要时创建类的实例

我有IBuilder<IConvertible> currentBuilder变量,但我无法创建任何Builder

的实例
this.currentBuilder = new SimpleBuilder(); //Doesn`t work

只有当我将IBuilder<IConvertible> currentBuilder更改为IBuilder<SimpleCollagePatterns> currentBuilder或其他类型时,我才能创建此类型的构建器,但我需要能够创建任何类型

5 个答案:

答案 0 :(得分:0)

我遇到了同样的情况。但最终发现没有解决方案。在运行时无法创建任何类型的对象。正如您所说,将IBuilder currentBuilder更改为IBuilder currentBuilder是为SimpleBuilder类型创建对象的唯一方法。同样适用于其他情况。

答案 1 :(得分:0)

如果你真的想在所有场景中使用一个变量,你总是可以将它定义为一个简单的对象来保持实例并使用IS运算符在必要时查看它实际上是哪种类型:

  

if(this.currentBuilder是SimpleBuilder)   {   }

答案 2 :(得分:0)

我相信您需要让您的IBuilder协变,请参阅https://msdn.microsoft.com/en-us/library/dd997386(v=vs.110).aspx

public interface IBuilder<out T>

答案 3 :(得分:0)

您想要阅读的内容称为协方差,在接口声明中的泛型类型参数旁边用关键字out表示。

public interface IBuilder<out T> where T: System.IConvertible{}

这将允许您声明类型为IBuilder<IConvertible>的变量并指定例如。 SimpleBuilder它,你只需要知道应用协方差的后果,最重要的是,用简单的话来说,泛型类型只能用作类型成员的返回类型。

如果您无法更改IBuilder界面,则无法为所有情况创建变量。

有关详细信息,您可以研究SO,例如。 Difference between Covariance & Contra-variance或在源头阅读,例如。 https://msdn.microsoft.com/en-us/library/mt654055.aspx

答案 4 :(得分:0)

如果您不需要公共访问泛型类型

特别是如果SimpleCollagePatterns由实现特定接口的类(在这种情况下为ShapeBuilder)专门使用,则您不需要协方差

有一种简单的设计模式仅依赖于继承。

例如:

public interface IBuilder {
    void Build();
}

public interface IBuilder<T> : IBuilder {
    T BuildParameter {get;}
}

注意:BuildParameter对应于您的BuildCollagePattern

然后你可以这样实现接口:

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

然后,您可以将任何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
    }
}

如前所述:一旦您需要访问实现IBuilder<T>的类之外的泛型类型,您需要开始区分类型并相应地转换它们。不那么优雅。

但是你可以用这种方式设计很多东西并保持可扩展性。我提出这个问题,因为我已经使用这种模式自己实现了图像过滤器,并且使用这种设计模式可以很好地实现BuildCollagePattern