jjo*_*son 3 c# generics reflection
我有一个有趣的问题.我想创建一个可以处理Reference类型和Nullable<T>类型的泛型类.基本上我想要的东西:
public class ClassWithNull<T>
{
public T varName = null;
}
Run Code Online (Sandbox Code Playgroud)
当然,这当然不会编译,因为并非所有类型都可以赋值为null,即不可为空的值类型.但问题是Nullable<T>价值类型,所以简单地添加where T : class并没有帮助我.我的泛型foo不是太强,但是我无法找到任何方式来说T必须是引用类型或可以为值的类型.
我必须解决这个问题的想法是创建ClassWithNull<T>一个抽象类.然后我可以添加两个子类,一个用于处理引用类型,另一个用于处理可空值类型.然后,基类中的静态工厂方法可以使用反射来确定应该构造哪个子类.就像是:
public static ClassWithNull<T> CreateClassWithNull<T>()
{
StackTrace st = new StackTrace();
Type type = st.GetFrame(1).GetMethod().GetGenericArguments()[0];
if (!type.IsValueType)
{
return new ClassWithReferenceType<T>();
}
else if (type == typeof(Nullable))
{
return new ClassWithNullableValueType<T>();
}
else
{
throw new Exception("Must provide nullable type.");
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是泛型是静态解决的.如果ClassWithReferenceType<U>期望U是引用类型,则new ClassWithReferenceType<T>()在工厂方法中调用是编译错误,因为T不需要是引用类型.编译器不知道运行时检查.
关于如何实现这样的事情的任何想法?
怎么样:
public class ClassWithNull<T>
{
public T varName = default(T);
}
Run Code Online (Sandbox Code Playgroud)
(实际上,你甚至不需要赋值 - 你可以将它保留为构造的默认值.但你可能想要default(T)局部变量.)
这不会阻止您使用不可为空的值类型错误地使用它 - 但这样就够了吗?
如果这对你没有帮助,我建议写两个静态方法,如下所示:
public static ClassWithNull<T> CreateClassWithNullForClass<T> where T : class
{
return new ClassWithReferenceType<T>();
}
public static ClassWithNull<T> CreateClassWithNullForNullable<T> where T : struct
{
return new ClassWithNullableValueType<T>();
}
Run Code Online (Sandbox Code Playgroud)
该字段ClassWithNullableValueType将是Nullable<T>- T将是基础类型.
现在,如果你想要相同方法的重载,那就会变得更难,特别是如果你不想传递任何参数.这是可能的,但实际上,真的非常可怕.
| 归档时间: |
|
| 查看次数: |
1169 次 |
| 最近记录: |