我有一个类,当前有几个采用整数参数的方法。这些整数映射到应用程序可以执行的操作。我想使类通用,以便类的使用者可以提供它们具有的所有操作的枚举类型,然后方法将采用该枚举类型的参数。但是,我希望它们能够根本不指定泛型类型,并将其默认返回到整数,而不改变当前方式的语法。这可能吗?
答案 0 :(得分:58)
那么......为什么不使用简单的继承呢?像:
class MyGenericClass<T>
{
}
class MyGenericClass : MyGenericClass<int>
{
}
这样你可以写两种方式:
var X = new MyGenericClass<string>();
var Y = new MyGenericClass(); // Is now MyGenericClass<int>
答案 1 :(得分:3)
保留原始版本(非通用版本)并创建它的通用版本。
然后从非通用版本调用通用版本。
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);
}
答案 2 :(得分:3)
你不能在类的定义中这样做:
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>();
答案 3 :(得分:1)
编译器可以根据传递的参数类型在大多数时间推断方法的类型参数:
public void DoSomething<T>(T test) {
}
可以用
调用DoSomething(4); // = DoSomething<int>(4);
DoSomething(MyEnum.SomeValue); // = DoSomething<MyEnum>(MyEnum.SomeValue);
顺便说一句,你也可以使用泛型方法的非泛型重载。
答案 4 :(得分: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;
}
}
答案 5 :(得分:0)
大多数情况下,编译器可以根据传递的参数类型推断字段的类型参数:
import lombok.Data;
@Data
public class MyClass<T> {
private T myField;
}
可以用作,
MyClass myClass = new MyClass();
String abc = "hello world !";
myClass.setMyField(abc);
System.out.println("test generic class with generic field = " + myGenericClass.getMyField());
这应该导致,
test generic class with generic field = hello world !