lda*_*dam 6 .net c# generics inheritance
我有一个界面,例如,为此看起来像这样:
interface IFoo<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable
{
TEnum MyEnum { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个抽象的基类,如下所示:
abstract class FooBase<TEnum> : IFoo<TEnum> where TEnum : struct, IConvertible, IFormattable, IComparable
{
public TEnum MyEnum { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我继承基类,如下所示:
class MyFoo : FooBase<MyFoo.MyFooEnum>
{
public enum MyFooEnum
{
Foo1,
Foo2,
}
}
Run Code Online (Sandbox Code Playgroud)
如何MyFoo使用类型参数从泛型方法实例化FooBase?
我几乎都在寻找这样的东西:
static class FooMethods
{
public static TFooClass GetFoo<TFooClass>() where TFooClass : FooBase, new()
{
TFooClass fooclass = new TFooClass();
return fooclass;
}
}
Run Code Online (Sandbox Code Playgroud)
FooBase我遇到的问题是它需要类型参数,但实际上我并不关心参数是什么,因为我MyFoo已经有了这些类型参数.
您可以从公共基础继承泛型类:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是您将无法使用 的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;
}
Run Code Online (Sandbox Code Playgroud)
更新:我可以指出的另一件事是,如果您发现需要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>();
Run Code Online (Sandbox Code Playgroud)