[英]How do I declare a DefaultValue attribute whose value is an array of strings?
我一直在代碼生成器中使用 DefaultValue 屬性,它從架構中編寫 C# 類定義。
我被困在架構中的屬性是一個字符串數組的地方。
我想在我的 C# 中寫這樣的東西:
[DefaultValue(typeof(string[]), ["a","b"])]
public string[] Names{get;set;}
但這不會編譯。
有什么方法可以成功聲明字符串數組的默認值屬性嗎?
另一種解決方案是利用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 不會經常被調用,但默認比較會。
同樣,只需確保您對如何使用該屬性有所了解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.