[英]How do I get the default value of an Enum using a non-generic Type?
I have a method that iterates through an object's properties and sets the values to their type's default values. 我有一个方法可以迭代对象的属性,并将值设置为其类型的默认值。 Some properties are enums.
一些属性是枚举。 I have another function that gets the default value of the enum (not 0), but it requires passing the enum type which is not known in the current method.
我有另一个函数,它获取枚举的默认值(不是0),但是它需要传递当前方法未知的枚举类型。
[DefaultValue(Red)]
public enum Colors
{
Red = 1,
green = 2
}
// In another class
public static TEnum GetDefaultValue<TEnum>() where TEnum : struct
{
Type t = typeof(TEnum);
DefaultValueAttribute[] attributes = (DefaultValueAttribute[])t.GetCustomAttributes(typeof(DefaultValueAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return (TEnum)attributes[0].Value;
}
else
{
return default(TEnum);
}
}
public static void ClearObject<T>(object obj)
{
obj = (T)obj;
PropertyInfo[] props = obj.GetType().GetProperties();
string propName = "";
try
{
foreach (PropertyInfo pi in props)
{
propName = pi.Name;
Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;
if (t.IsEnum)
{
// This works
// var val = EnumFunctions.GetDefaultValue<Colors>();
// The error is here
var val = EnumFunctions.GetDefaultValue<t>();
// ^^^
pi.SetValue(obj, val);
}
// In case of nullable value types int,datetime, etc - set null
else if (Nullable.GetUnderlyingType(pi.PropertyType) != null)
pi.SetValue(obj, null);
else
pi.SetValue(obj, null, null);
}
}
catch (Exception e)
{
string msg = $"Error for {propName}: {e.Message}";
throw new Exception(msg);
}
}
I've tried typeof(t)
, t.GetType()
. 我已经尝试过
typeof(t)
, t.GetType()
。
I want the default value for a Colors enum property to be Red. 我希望Colors枚举属性的默认值为Red。 The line causing the error is
导致错误的行是
var val = EnumFunctions.GetDefaultValue<t>();
Error CS0118 't' is a variable but is used like a type
You don't need generics here 您在这里不需要泛型
public static object GetDefaultValue(Type type)
{
DefaultValueAttribute[] attributes = (DefaultValueAttribute[])type.GetCustomAttributes(typeof(DefaultValueAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return attributes[0].Value;
}
else
{
return null;
}
}
And then you use it like this 然后像这样使用它
var val = EnumFunctions.GetDefaultValue(t);
if(val != null)
pi.SetValue(obj, val);
Source of your confusion: 您的困惑之源:
Generally speaking, generics are not runtime construct, they're compile-time construct, so you can't use them in reflection, because reflection works at run time. 一般来说,泛型不是运行时构造,它们是编译时构造,因此您不能在反射中使用它们,因为反射在运行时起作用。
您也可以像这样通过反射调用该方法:
typeof(EnumFunctions).GetMethod("GetDefaultValue").MakeGenericMethod(t).Invoke(null, null);
Per my comment above (thought I could post code). 根据我上面的评论(我可以发布代码)。 I also wanted to ensure that enums were instantiated to a valid value.
我还想确保将枚举实例化为有效值。 Some enums do not have a 0 so the default of numeric types wouldn't work.
某些枚举没有0,因此默认的数字类型不起作用。
public MyClass()
{
// Sets default property values for all but dates
Basefunctions.Clear<InternalExaminer>(this);
// Sets default values by [DefalutValue()] tag.
foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(this))
{
pd.ResetValue(this);
}
// Sets date properties to current date.
Basefunctions.SetDates<MyClass>(this);
}
public static class Basefunctions
{
public static void SetDates<T>(object obj)
{
string propName = "";
try
{
obj = (T)obj;
PropertyInfo[] props = obj.GetType().GetProperties()
.Where(p => p.PropertyType == typeof(DateTime)).ToArray();
if (props != null)
{
DateTime date = DateTime.Now;
foreach (PropertyInfo pi in props)
{
propName = pi.Name;
if (Nullable.GetUnderlyingType(pi.PropertyType) == null)
pi.SetValue(obj, date);
}
}
}
catch (Exception e)
{
throw new Exception($"Could not set date for {propName}.\n{e.Message}");
}
}
public static void Clear<T>(object obj)
{
obj = (T)obj;
PropertyInfo[] props = obj.GetType().GetProperties();
string propName = "";
try
{
foreach (PropertyInfo pi in props)
{
propName = pi.Name;
Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;
if (Nullable.GetUnderlyingType(pi.PropertyType) != null)
pi.SetValue(obj, null);
else
{
var val = GetDefaultVal(t);
if (t.IsEnum)
{
// In case enum does not have a 0
if (!Enum.IsDefined(t, val))
val = EnumMin(pi.PropertyType);
}
pi.SetValue(obj, val);
}
}
}
catch (Exception e)
{
string msg = $"Error for {propName}: {e.Message}";
throw new Exception(msg);
}
}
private static object GetDefaultVal(Type type)
{
DefaultValueAttribute att = (DefaultValueAttribute)type.GetCustomAttribute(typeof(DefaultValueAttribute));
if (att != null)
return att.Value;
else
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
private static object EnumMin(Type t)
{
Array x = Enum.GetValues(t);
var ret = x.GetValue(0);
return ret;
}
private static object EnumMax(Type t)
{
Array x = Enum.GetValues(t);
var ret = x.GetValue(x.Length - 1);
return ret;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.