接口中的C#泛型类型作为占位符?

时间:2016-09-27 22:28:28

标签: c# generics inheritance factory

我正在尝试执行以下操作 -

interface I1<PlaceHolder> {}
class C1 : I1<ActualClass> {
public Method() { ActualClass class = new ActualClass();}}

它有效,但C#不允许以下 -

interface IFactory<PlaceHolder> { I1 Create<PlaceHolder>(); } 
class ConcreteFactory<ActualClass> {
public I1 Create<ActualClass>() { return new C1(); //Won't work }
}

如果我尝试将通用类型添加到C1,则以下内容将无效

class C1<ActualClass> : I1<ActualClass> {
    public Method() { ActualClass class = new ActualClass(); //Won't work}
}

我想知道C#是否允许通过其语言功能实现上述功能?

编辑1

请参阅下面一个更真实的上述示例(ValidationResultA和ValidationResultB是不共享基类并且可能具有不同属性的具体类) -

interface IProcessor<Validator, ValidationResult> { 
ValidationResult ValidateProcess(); 
void RunProcess();
}

class ProcessorA : IProcessor<ValidatorA, ValidationResultA> {
ValidationResultA ValidateProcess() {
    ValidatorA validator = new ValidatorA();
    ValidationResultA result = validator.DoSomething();
    result.IsAAA = true;
    return result;
}

class ProcessorB : IProcessor<ValidatorB, ValidationResultB> {
ValidationResultB ValidateProcess() {
    ValidationResultB validator = new ValidationResultB();
    ValidationResultB result = validator.DoSomething();
    result.IsBBB = true;
    return validator;
}

然后我们可以创建返回IProcess的ProcessorFactory。

我们用这个做了两件事 - 1.我们能够在返回类型上重载ValidateProcess'。 2.我们能够创建IProcessor的实现,并在其中插入各种Validators和ValidationResults。

3 个答案:

答案 0 :(得分:1)

如果要创建泛型类型的新实例,则需要

class MyClass<T> where T : new()

所以: -

interface I1<PlaceHolder>
{        
}
class C1<ActualClass> : I1<ActualClass> where ActualClass: new()
{
    public void Method()
    {
        ActualClass c = new ActualClass();
    }
}

interface IFactory<PlaceHolder> where PlaceHolder : new()
{
    I1<PlaceHolder> Create<PlaceHolder>(); 

}
class ConcreteFactory<ActualClass>  where ActualClass : new()
{
    public I1<ActualClass> Create()
    {
        return new C1<ActualClass>(); 
    }
}

答案 1 :(得分:1)

从你的问题中不清楚你想要实现什么,但似乎你需要通用约束来解决这个问题。您可以使用一些不同的约束:

  • T必须有一个空构造函数:public class MyClass<T> where T : new()
  • T继承/实现基类/接口:public class MyClass<T> where T : SomeOtherClass
  • T是一个班级:public class MyClass<T> where T : class
  • T是一个结构:`public class MyClass,其中T:struct

您可以通过用逗号分隔它们来结合上述内容,请记住new()约束始终需要最后,例如:

// T must implement IDisposable, inherit from SomeClass and have a public 
// parameterless constructor
public class MyClass<T> where T : IDisposable, SomeClass, new()

考虑到这一点,您所追求的“我认为”是以下解决方案:

interface I1<T>
{
}

class ActualClass
{
}

class C1 : I1<ActualClass>
{
    public C1()
    {
        ActualClass class1 = new ActualClass();
    }
}

interface IFactory
{
    I1<T> Create<T>();
}

class ConcreteFactory
{
    public I1<T> Create<T>() where T : I1<T>, new()
    {
        return new T(); 
    }
}

为什么你想要这样做,超出我的范围,但上述实施工作正常。您可以使用通用约束来查看是否解决了问题。

在另一种情况下,最好修改你的问题并给我们一个真实的例子。

答案 2 :(得分:1)

编译:

interface I1<PlaceHolder> where PlaceHolder : new()  { }

class ActualClass {}

class C1 : I1<ActualClass> 
{
   public void Method() { ActualClass @class = new ActualClass();}
}

interface IFactory<PlaceHolder> where PlaceHolder : new() 
{
   I1<PlaceHolder> Create();  
} 

class ConcreteFactory : IFactory<ActualClass>
{
   public I1<ActualClass> Create() { return new C1(); }
}