另一个解决方案是利用DefaultValueAttribute 的虚拟特性并派生出你自己的。下面是一些非常量类型的示例。
用法示例:
public class Foo
{
[DefaultValueNew( typeof(List<int>), new int[]{2,2} )]
public List<int> SomeList { get; set; }
// -- Or --
public static List<int> GetDefaultSomeList2() => new List<int>{2,2};
[DefaultValueCallStatic( typeof(Foo), nameof(GetDefaultSomeList2) )]
public List<int> SomeList2 { get; set; }
};
以下是这些属性的定义:
public class DefaultValueNewAttribute : DefaultValueAttribute
{
public Type Type { get; }
public object[] Args { get; }
public DefaultValueNewAttribute(Type type, params object[] args)
: base(null)
{
Type = type;
Args = args;
}
public override object? Value => Activator.CreateInstance(Type, Args);
};
public class DefaultValueCallStaticAttribute : DefaultValueAttribute
{
public Type Type { get; }
public string Method { get; }
public DefaultValueCallStaticAttribute(Type type, string method)
: base(null)
{
Type = type;
Method = method;
}
public override object? Value => Type.GetMethod(Method, BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
};
需要注意的问题
定义自己的DefaultValueAttribute 时要小心。最重要的是,在创建它之前先了解一下如何使用它。对于像代码生成器这样的东西,上面可能没问题。但是,如果您将它与 Newtonsoft Json 或主要仅使用它来比较值的东西一起使用,那么您可能希望其中的值更加恒定,以节省时间而不是每次都重新创建对象。
对于您不希望每次都重新创建值的情况,您可以执行以下操作:
public static readonly List<int> DefaultAges = new List<int>{2,2};
private List<int> __ages = new List<int>(DefaultAges);
[DefaultValueStatic( typeof(List<int>), nameof(DefaultAges) )]
public List<int> Ages { get => __ages; set {__ages = new List<int>(value);}
其中属性DefaultValueStatic定义为:
public class DefaultValueStaticAttribute : DefaultValueAttribute
{
public DefaultValueStaticAttribute(Type type, string memberName) : base(null)
{
foreach (var member in type.GetMember( memberName, BindingFlags.Static | BindingFlags.Public ))
{
if (member is FieldInfo fi) { SetValue(fi.GetValue(type)); return; }
if (member is PropertyInfo pi) { SetValue(pi.GetValue(type)); return; }
}
throw new ArgumentException($"Unable to get static member '{memberName}' from type '{type.Name}'");
}
};
以上版本将确保不会重新创建默认值。这对于像 Newtonsoft json 这样的东西很有用,其中 setter 不会经常被调用,但默认比较会。
同样,请确保您了解该属性的使用方式。