您可以:
对于' Text '值,您可以使用DescriptionAttribute。
对于其他两个,我认为您应该创建新属性。
Helper.GetExtraInfo(MyType val)
Get enum from enum attribute包含用于读取属性值的扩展方法。
,
在tymtam和Kevin的共同帮助下,我做到了:
void Main()
{
Reason.NotEnoughStock.GetAttributeOfType<DescriptionAttribute>().Description;
Reason.ProductNotAvailabe.GetAttributeOfType<ResponsabilityAttribute>().Responsability;
}
public enum Reason
{
[Description("There is not enough stock")]
[Valid(true)]
[Responsability("company")]
NotEnoughStock,[Description("Produc is not available")]
[Valid(false)]
[Responsability("company")]
ProductNotAvailabe,[Description("Payment is not done")]
[Valid(false)]
[Responsability("client")]
PaymentNotDone,[Description("Client is black listed")]
[Valid(false)]
[Responsability("client")]
BlackListedClient,[Description("There is not enough time")]
[Valid(true)]
[Responsability("company")]
NotEnoughTime
}
public static class EnumHelper
{
/// <summary>
/// Gets an attribute on an enum field value
/// </summary>
/// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
/// <param name="enumVal">The enum value</param>
/// <returns>The attribute of type T that exists on the enum value</returns>
/// <example>string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;</example>
public static T GetAttributeOfType<T>(this Enum enumVal) where T : System.Attribute
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(T),false);
return (attributes.Length > 0) ? (T)attributes[0] : null;
}
}
public class ValidAttribute : Attribute
{
public bool Valid;
public ValidAttribute(bool valid) { Valid = valid; }
}
public class ResponsabilityAttribute : Attribute
{
public string Responsability;
public ResponsabilityAttribute(string responsability) { Responsability = responsability; }
}
,
您可以为枚举创建扩展方法,以便您仍然可以享受枚举并在Reason对象中获取数据。
var reason = Reason.NotEnoughStock.GetReasonInfo(ReasonData);
样品
internal class Program
{
public static void Main(string[] args)
{
var reason = ReasonConstant.Reason.NotEnoughStock.GetReasonInfo(ReasonData);
}
}
public static class ReasonUtils
{
public static ReasonInfo GetReasonInfo(this ReasonConstant.Reason reason,Dictionary<ReasonConstant.Reason,ReasonInfo> reasonData)
{
if (reasonData == null)
return null;
if (!reasonData.ContainsKey(reason))
return null;
else
return reasonData[reason];
}
}
public class ReasonInfo
{
public bool IsValid { get; set; }
public string Responsability { get; set; }
public string Text { get; set; }
}
public static class ReasonConstant
{
public enum Reason
{
NotEnoughStock,// Valid = yes,Responsability = company,Text = There is not enough stock
ProductNotAvailabe,// Valid = no,Text = Produc is not available
PaymentNotDone,Responsability = client,Text = Payment is not done
BlackListedClient,Text = Client is black listed
NotEnoughTime // Valid = yes,Text = There is not enough time
}
}
,
您的样本看起来可能是:
public enum Reason
{
None = 0,Valid = 1,CompanyResponsible = 2,ClientResponsible = 4,Text = There is not enough stock
[Description("There is not enough stock")
NotEnoughStock = Valid | CompanyResponsible | 8,...
// Valid = yes,Text = There is not enough time
[Description("There is not enough time")
NotEnoughTime = Valid | CompanyResponsible | 128,}
也许您可以排除一些单独的概念来替换| 8
部分。
,
没有任何方法可以简单地实现目标。
您必须手动执行所需的行为。
您可能会考虑创建一个类,使其具有良好而适当的设计以及能够简单有效地使用它,因为实际上您询问如何创建以枚举值作为键的实例的字典。
如此:
Reason.cs
public enum Reason
{
NotEnoughStock,ProductNotAvailabe,PaymentNotDone,BlackListedClient,NotEnoughTime
}
您可以创建此枚举:
Responsability.cs
public enum Responsability
{
None,Company,Client
}
此类允许在实例中存储枚举的元数据,并提供在静态构造函数中初始化的枚举类型的所有元数据的静态列表:
ReasonMetaData.cs
using System.Collections.Generic;
public class ReasonMetaData
{
static public Dictionary<Reason,ReasonMetaData> All { get; private set; }
static ReasonMetaData()
{
All = new Dictionary<Reason,ReasonMetaData>();
All.Add(
Reason.NotEnoughStock,new ReasonMetaData(Responsability.Company,true,"There is not enough stock"));
All.Add(
Reason.ProductNotAvailabe,false,"Product is not available"));
All.Add(
Reason.PaymentNotDone,new ReasonMetaData(Responsability.Client,"Payment is not done"));
All.Add(
Reason.BlackListedClient,"Client is black listed"));
All.Add(
Reason.NotEnoughTime,"There is not enough time"));
}
static public ReasonMetaData Get(Reason reason)
{
if ( All.ContainsKey(reason) )
return All[reason];
else
return null;
}
public Responsability Responsability { get; private set; }
public bool Valid { get; private set; }
public string Text { get; private set; }
public override string ToString()
{
return $"Responsability = {Enum.GetName(typeof(Responsability),Responsability)}," +
$"Valid = {( Valid ? "yes" : "no" )}" +
$"Text = {Text}";
}
private ReasonMetaData()
{
}
private ReasonMetaData(Responsability responsability,bool valid,string text)
{
Responsability = responsability;
Valid = valid;
Text = text;
}
}
您还可以按照@RawitasKrungkaew的建议创建扩展方法:
ReasonMetadataHelper.cs
static public class ReasonMetadataHelper
{
static public ReasonMetaData GetMetaData(this Reason reason)
{
return ReasonMetaData.Get(reason);
}
}
使用和测试
static void Test()
{
Console.WriteLine("Metadata of Reason.NotEnoughStock is:");
Console.WriteLine(Reason.NotEnoughStock.GetMetaData());
Console.WriteLine("");
Console.WriteLine("Metadata of Reason.ProductNotAvailabe is:");
Console.WriteLine(ReasonMetaData.Get(Reason.ProductNotAvailabe));
Console.WriteLine("");
Console.WriteLine("All metadata of Reason enum are:");
foreach ( var item in ReasonMetaData.All )
Console.WriteLine($" {item.Key}: {item.Value}");
}
输出
Metadata of Reason.NotEnoughStock is:
Responsability = Company,Valid = yes,Text = There is not enough stock
Metadata of Reason.ProductNotAvailabe is:
Responsability = Company,Valid = no,Text = Product is not available
All metadata of Reason enum are:
NotEnoughStock: Responsability = Company,Text = There is not enough stock
ProductNotAvailabe: Responsability = Company,Text = Product is not available
PaymentNotDone: Responsability = Client,Text = Payment is not done
BlackListedClient: Responsability = Client,Text = Client is black listed
NotEnoughTime: Responsability = Company,Text = There is not enough time
改进
您可以将此解决方案与属性混合使用,以通过解析枚举项的属性来自动创建列表:
如此:
ReasonAttributes.cs
public class ReasonResponsabilityAttribute : Attribute
{
public Responsability Responsability { get; private set; }
public ReasonResponsabilityAttribute(Responsability responsability)
{
Responsability = responsability;
}
}
public class ReasonValidAttribute : Attribute
{
public bool Valid { get; private set; }
public ReasonValidAttribute(bool valid)
{
Valid = valid;
}
}
public class ReasonTextAttribute : Attribute
{
public string Text { get; private set; }
public ReasonTextAttribute(string text)
{
Text = text;
}
}
Reason.cs现在是:
public enum Reason
{
[ReasonResponsability(Responsability.Company)]
[ReasonValid(true)]
[ReasonText("There is not enough stock")]
NotEnoughStock,// ...
ProductNotAvailabe,// ...
PaymentNotDone,// ...
BlackListedClient,// ...
NotEnoughTime
}
ReasonMetadata.cs静态构造函数现在为:
using System.Reflection;
static ReasonMetaData()
{
All = new Dictionary<Reason,ReasonMetaData>();
var list = Enum.GetValues(typeof(Reason));
foreach ( Reason reason in list )
{
var metadata = new ReasonMetaData();
var memberinfo = reason.GetType().GetMember(Enum.GetName(typeof(Reason),reason));
if ( memberinfo.Length == 1 )
{
var attributes = memberinfo[0].GetCustomAttributes();
foreach ( Attribute attribute in attributes )
if ( attribute is ReasonResponsabilityAttribute )
metadata.Responsability = ( (ReasonResponsabilityAttribute)attribute ).Responsability;
else
if ( attribute is ReasonValidAttribute )
metadata.Valid = ( (ReasonValidAttribute)attribute ).Valid;
else
if ( attribute is ReasonTextAttribute )
metadata.Text = ( (ReasonTextAttribute)attribute ).Text;
}
All.Add(reason,metadata);
}
}
仅使用一个属性
ReasonMetadataAttribute.cs
public class ReasonMetadataAttribute : Attribute
{
public Responsability Responsability { get; private set; }
public bool Valid { get; private set; }
public string Text { get; private set; }
public ReasonMetadataAttribute(Responsability responsability,string text)
{
Responsability = responsability;
Valid = valid;
Text = text;
}
}
ReasonMetadata.cs静态构造函数现在为:
static ReasonMetaData()
{
All = new Dictionary<Reason,reason));
if ( memberinfo.Length == 1 )
{
var attributes = memberinfo[0].GetCustomAttributes();
foreach ( Attribute attribute in attributes )
if ( attribute is ReasonMetadataAttribute )
{
var metadataAttribute = (ReasonMetadataAttribute)attribute;
metadata.Responsability = metadataAttribute.Responsability;
metadata.Valid = metadataAttribute.Valid;
metadata.Text = metadataAttribute.Text;
}
}
All.Add(reason,metadata);
}
}
用法:
public enum Reason
{
[ReasonMetadata(Responsability.Company,"There is not enough stock")]
NotEnoughStock,// ...
NotEnoughTime
}
,
创建一个类来存储其他信息,例如ReasonDetail
,然后使用Dictionary<Reason,ReasonDetail>
并提供Reason
和ReasonDetail
之间的映射