如何为泛型提供默认类型?

Max*_*ing 28 .net c# generics .net-2.0

我有一个类,目前有几个采用整数参数的方法.这些整数映射到应用程序可以执行的操作.我想使类通用,以便类的使用者可以提供它们具有的所有操作的枚举类型,然后方法将采用该枚举类型的参数.但是,我希望它们能够根本不指定泛型类型,并将其默认返回到整数,而不会改变当前方式的语法.这可能吗?

Vil*_*lx- 80

那么......为什么不使用简单的继承呢?喜欢:

class MyGenericClass<T>
{
}

class MyGenericClass : MyGenericClass<int>
{
}
Run Code Online (Sandbox Code Playgroud)

这样你可以写两种方式:

var X = new MyGenericClass<string>();
var Y = new MyGenericClass(); // Is now MyGenericClass<int>
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案,应该被接受. (10认同)

Mic*_*ows 9

你不能在类的定义中这样做:

var foo = new MyGenericClass(); // defaults to integer... this doesn't work
var bar = new MyGenericClass<MyEnum>(); // T is a MyEnum
Run Code Online (Sandbox Code Playgroud)

如果真的重视默认类型为 int 的隐含性,则必须使用静态工厂方法来实现,尽管我没有看到它的价值。

public class MyGenericClass<T>
{
    public static MyGenericClass<T> Create()
    {
        return new MyGenericClass<T>();
    }
    public static MyGenericClass<int> CreateDefault()
    {
        return new MyGenericClass<int>();
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅下文,了解您如何真正无法从上述内容中受益。

var foo = MyGenericClass<MyEnum>.Create();
var bar1 = MyGenericClass.CreateDefault(); // doesn't work
var bar2 = MyGenericClass<int>.CreateDefault(); // works, but what's the point
Run Code Online (Sandbox Code Playgroud)

如果你想更进一步,你可以创建一个静态工厂类来解决这个问题,但如果你这样做只是为了提供默认类型,那么这是一个更荒谬的解决方案:

public static class MyGenericClassFactory
{
    public static MyGenericClass<T> Create<T>()
    {
        return new MyGenericClass<T>();
    }
    public static MyGenericClass<int> Create()
    {
        return new MyGenericClass<int>();
    }
}

var foo = MyGenericClassFactory.Create(); // now we have an int definition
var bar = MyGenericClassFactory.Create<MyEnum>();
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是不完整的 - 它错过了实现所需默认值的非常简单的方法。请参阅下面的 Vilx- 的回答。 (5认同)
  • 是的,我不想介绍这种复杂性。默认值并不是非常重要,它本来很好。我不知道有什么方法可以做到,但我想先和你们所有人确认一下。谢谢你的回答 (2认同)

J.W*_*.W. 7

保留您的原始版本(非通用版本)并创建它的通用版本。

然后从非通用版本调用通用版本。

void Main()
{
DoSomething(2);
DoSomething(EnumValue);

}

public void DoSomething(int test) {
DoSomething<int>(test);
}

// Define other methods and classes here
public void DoSomething<T>(T test) {
Console.WriteLine(test);
}
Run Code Online (Sandbox Code Playgroud)