我无法通过通用变量传递可以为空的枚举。
我目前正在使用反射为泛型类创建属性设置器。 这是代码
public static class program
{
static void Main(string[] args)
{
someClass testclass = new someClass();
PropertyInfo enumProperty = typeof(someClass).GetProperties()[0];
Action<someClass, int> enumDelegate = CreateSetterFromPropertyInfo<someClass, int>(enumProperty);
enumDelegate(testclass, 2);
Console.WriteLine(testclass.enumVal.ToString()); // writes B
object nullableSetter = null;
PropertyInfo enumPropertyNullable = typeof(someClass).GetProperties()[1];
if (enumPropertyNullable.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (enumPropertyNullable.PropertyType.GetGenericArguments().First().IsEnum)
{
// the step below determines the method signature. I cannot deviate from what the property tells me.
// if I use int? instead of the PropertyType I get an ArgumentException.
MethodInfo method = typeof(program).GetMethod("CreateSetterFromPropertyInfo", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(new Type[] { typeof(someClass), enumPropertyNullable.PropertyType });
nullableSetter = method.Invoke(null, new object[] { enumPropertyNullable });
}
}
if (nullableSetter != null)
{
Action<someClass, someEnum?> cast1 = (Action<someClass, someEnum?>) nullableSetter;
Action<someClass, Nullable<someEnum>> cast2 = (Action<someClass, Nullable<someEnum>>)nullableSetter;
// Action<someClass, Nullable<int>> cast3 = (Action<someClass, Nullable<int>>)nullableSetter;
// Action<someClass, Enum> cast4 = (Action<someClass, Enum>)nullableSetter;
// at this point I am trying to cast a string to a enum. That works. However the parameter should be a nullable enum.
Type subtype = enumPropertyNullable.PropertyType.GetGenericArguments().First();
Enum result = Enum.Parse(subtype, "B") as Enum;
// here is where I am getting the error. I can't find a way to cast the string I have to a nullable enum.
//cast1(testclass, result);
}
}
private static Action<C, P> CreateSetterFromPropertyInfo<C, P>(PropertyInfo property)
{
Action<C, P> setForAnyProperty = (Action<C, P>)Delegate.CreateDelegate(typeof(Action<C, P>), null, property.GetSetMethod());
return setForAnyProperty;
}
public class someClass
{
public someEnum enumVal {get; set;}
public someEnum? enumValNullable { get; set; }
}
public enum someEnum
{
A = 1,
B = 2
}
}
我只会遇到可以为空的枚举问题,而不是正常的枚举问题。如果您运行该示例,您可以看到使用带有整数作为签名的委托,代码运行正常。
问题当可空的枚举迫使我在委托制定者签名中使用枚举本身时。当我实际上尝试用值填充对象时,代码没有引用有问题的枚举,这是使用泛型的一点。我也不确定为什么我不能使用int?对于可以为空的枚举。欢迎任何见解!
此时我很想使用PropertyInfo.SetValue方法而不是委托。它似乎有效。
答案 0 :(得分:1)
更新:下面的新NullableEnumCopier类不了解someClass或someEnum。
public static class program
{
static void Main(string[] args)
{
someClass testclass = new someClass();
NullableEnumCopier<someClass, someEnum>.Copy(testclass);
}
public static class NullableEnumCopier<TClass, TEnum> where TEnum : struct
{
public static void Copy(TClass item)
{
PropertyInfo enumProperty = typeof(TClass).GetProperties()[0];
Action<TClass, int> enumDelegate = CreateSetterFromPropertyInfo<TClass, int>(enumProperty);
enumDelegate(item, 2);
//Console.WriteLine(item.enumVal.ToString()); // writes B
object nullableSetter = null;
PropertyInfo enumPropertyNullable = typeof(TClass).GetProperties()[1];
if (enumPropertyNullable.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (enumPropertyNullable.PropertyType.GetGenericArguments().First().IsEnum)
{
// the step below determines the method signature. I cannot deviate from what the property tells me.
// if I use int? instead of the PropertyType I get an ArgumentException.
MethodInfo method = typeof(program).GetMethod("CreateSetterFromPropertyInfo", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(new Type[] { typeof(TClass), enumPropertyNullable.PropertyType });
nullableSetter = method.Invoke(null, new object[] { enumPropertyNullable });
}
}
if (nullableSetter != null)
{
Action<TClass, TEnum?> cast1 = (Action<TClass, TEnum?>) nullableSetter;
Action<TClass, Nullable<TEnum>> cast2 = (Action<TClass, Nullable<TEnum>>)nullableSetter;
// Action<TClass, Nullable<int>> cast3 = (Action<TClass, Nullable<int>>)nullableSetter;
// Action<TClass, Enum> cast4 = (Action<TClass, Enum>)nullableSetter;
// at this point I am trying to cast a string to a enum. That works. However the parameter should be a nullable enum.
Type subtype = enumPropertyNullable.PropertyType.GetGenericArguments().First();
Enum result = Enum.Parse(subtype, "B") as Enum;
// here is where I am getting the error. I can't find a way to cast the string I have to a nullable enum.
cast1(item, (TEnum?)(object)result);
}
}
}
private static Action<C, P> CreateSetterFromPropertyInfo<C, P>(PropertyInfo property)
{
Action<C, P> setForAnyProperty = (Action<C, P>)Delegate.CreateDelegate(typeof(Action<C, P>), null, property.GetSetMethod());
return setForAnyProperty;
}
public class someClass
{
public someEnum enumVal {get; set;}
public someEnum? enumValNullable { get; set; }
}
public enum someEnum
{
A = 1,
B = 2
}
}