C# 你如何为泛型提供默认类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1099440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:12:36  来源:igfitidea点击:

How do you provide a default type for generics?

c#.netgenerics.net-2.0

提问by Max Schmeling

I have a class that currently has several methods that take integer parameters. These integers map to operations that the application can perform. I'd like to make the class generic so that the consumers of the class can provide an enum type that they have with all the operations in it, then the methods will take parameters of that enum type. However, I want them to be able to not specify a generic type at all, and have it default back to integers with no change in syntax from the current way. Is this possible?

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

采纳答案by Michael Meadows

You can't do it in the definition of the class:

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

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

If really value the implicitness of the default type being int, you'll have to do it with a static factory method, although I don't see the value of it.

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

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

See below for how you really don't benefit from the above.

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

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

If you want to take it even farther, you can create a static factory class that will solve this, but that's an even more ridiculous solution if you're doing it for no other reason than to provide a default type:

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

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>();

回答by Mehrdad Afshari

The compiler can infer the type arguments on methodsmost of the time based on the type of the arguments passed:

大多数情况下,编译器可以根据传递的参数类型推断方法的类型参数:

public void DoSomething<T>(T test) {
}

can be called with

可以用

DoSomething(4);                   // = DoSomething<int>(4);
DoSomething(MyEnum.SomeValue);    // = DoSomething<MyEnum>(MyEnum.SomeValue);

By the way, you can have non-generic overloads of a generic method too.

顺便说一句,您也可以拥有泛型方法的非泛型重载。

回答by J.W.

Keep your original version (non-generic version) and create a generic version of it.

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

Then call the generic version from your non-generic version.

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

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

回答by Vilx-

So... why not use simple inheritance? Like:

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

class MyGenericClass<T>
{
}

class MyGenericClass : MyGenericClass<int>
{
}

This way you can write both ways:

这样你就可以两种方式写:

var X = new MyGenericClass<string>();
var Y = new MyGenericClass(); // Is now MyGenericClass<int>