接口基类通过泛型方法实例化

时间:2015-10-22 15:48:38

标签: c# .net generics inheritance

我有一个界面,例如'故事如下:

interface IFoo<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable
{
  TEnum MyEnum { get; set; }
}

然后我有一个如下所示的抽象基类:

abstract class FooBase<TEnum> : IFoo<TEnum> where TEnum : struct, IConvertible, IFormattable, IComparable
{
  public TEnum MyEnum { get; set; }
}

然后我继承基类,如下:

class MyFoo : FooBase<MyFoo.MyFooEnum>
{
  public enum MyFooEnum
  {
    Foo1,
    Foo2,
  }
}

如何从类型参数为MyFoo的泛型方法中实例化FooBase

我几乎都在寻找这样的东西:

static class FooMethods
{
  public static TFooClass GetFoo<TFooClass>() where TFooClass : FooBase, new()
  {
    TFooClass fooclass = new TFooClass();
    return fooclass;
  }
}

我遇到的问题是它需要FooBase的类型参数,但实际上我并不关心参数是什么,因为我的MyFoo已经具有这些类型参数。

2 个答案:

答案 0 :(得分:3)

您可以从公共基础继承您的泛型类:

abstract class FooBase {
}

abstract class FooBase<TEnum> : FooBase, IFoo<TEnum>
where TEnum : struct, IConvertible, IFormattable, IComparable {
   public TEnum MyEnum { get; set; }
}

public static TFooClass GetFoo<TFooClass>()
where TFooClass : FooBase, new() {
   TFooClass fooclass = new TFooClass();
   return fooclass;
}

但是您将无法使用MyEnum的通用约束来访问FooBase属性。 (如果没有指定类型,你怎么能这样做?)

那,或者您需要向GetFoo添加另一个类型参数:

abstract class FooBase<TEnum> : IFoo<TEnum>
where TEnum : struct, IConvertible, IFormattable, IComparable {
   public TEnum MyEnum { get; set; }
}

public static TFooClass GetFoo<TFooClass, TEnum>()
where TFooClass : FooBase<TEnum>, new()
where TEnum : struct, IConvertible, IFormattable, IComparable {
   TFooClass fooclass = new TFooClass();
   return fooclass;
}

更新:我可以指出的另一件事是,如果你发现你需要经常调用这个GetFoo方法,那么如果你把它放在一个实例类而不是静态类中,你可以推一个或者两个类型参数都在类中,而不是总是在方法中指定它。这可以使一些代码更简洁,但实际上只有你调用这个方法很多。例如:

public sealed FooFactory<TEnum>
where TEnum : struct, IConvertible, IFormattable, IComparable {
   public static TFooClass GetFoo<TFooClass>()
   where TFooClass : FooBase<TEnum>, new() {
      TFooClass fooclass = new TFooClass();
      return fooclass;
   }
}

...

var factory = new FooFactory<SomeEnum>();
var foo1 = factory.GetFoo<SomeFooClass1>();
var foo2 = factory.GetFoo<SomeFooClass2>();

// or the other way:

var factory = new FooFactory<SomeFooClass>();
var foo1 = factory.GetFoo<SomeEnum1>();
var foo2 = factory.GetFoo<SomeEnum2>();

答案 1 :(得分:0)

你可以做下一个:

abstract class FooBase
{
}

abstract class FooBase<TEnum> : FooBase, IFoo<TEnum> where TEnum : struct, IConvertible, IFormattable, IComparable
{
  public TEnum MyEnum { get; set; }
}

static class FooMethods
{
  public static TFooClass GetFoo<TFooClass>() where TFooClass : FooBase, new()
  {
    TFooClass fooclass = new TFooClass();
    return fooclass;
  }
}