如何为属类提供一个默认类型?

问题描述 投票:30回答:5

我有一个类,目前有几个方法都是取整数参数。这些整数映射到应用程序可以执行的操作。我想让这个类成为通用类,这样这个类的消费者就可以提供一个他们拥有的包含所有操作的枚举类型,然后这些方法就会接受这个枚举类型的参数。但是,我希望他们能够完全不指定一个通用类型,让它默认回到整数,而语法与当前的方式没有变化。这可能吗?

c# .net generics .net-2.0
5个回答
4
投票

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

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

如果真的想让默认类型是int的隐含性, 你必须用静态工厂方法来做,虽然我不知道它的价值。

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

请看下面的内容,你真的无法从上面得到好处。

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

如果你想走得更远,你可以创建一个静态工厂类来解决这个问题,但如果你这样做的原因不是为了提供一个默认类型,那就是一个更可笑的解决方案。

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

95
投票

所以... 为什么不使用简单的继承?像这样。

class MyGenericClass<T>
{
}

class MyGenericClass : MyGenericClass<int>
{
}

这样你就可以两边都写

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

4
投票

保留你的原始版本(非通用版本) 并创建一个通用版本.

然后从你的非通用版本中调用通用版本。

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

1
投票

编译器可以推断出类型参数在 方法 大多数时候是基于传递的参数类型。

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

可以用

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

顺便说一下,你也可以有非通用方法的重载。


0
投票

我相信你已经离开了这个问题,然而我在处理类似的问题时发现了这个解决方案,它使用了一个我不熟悉的 "使用 "的上下文。 他们需要把它放在他们的命名空间中,所以它并不完全完美。

namespace mygeneric
{
    public class SecurityContext<T>
    {

    }
}

namespace mytest
{
    using SecurityContext = mygeneric.SecurityContext<int>;
    using mygeneric;

    enum MyContexts
    {
        User,
        Admin
    }
    class MyTest
    {
        SecurityContext myDefaultContext;
        SecurityContext<MyContexts> mySpecialContext;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.