Нет ничего доступного для достижения вашей цели простым способом.
Вы должны вручную реализовать необходимое поведение.
Вы можете подумать о создании класса, который бы имел хорошее и правильное поведение. дизайн, а также возможность простого и эффективного использования, потому что на самом деле вы спрашиваете, как создать словарь экземпляров, снабженных ключом значением перечисления.
Таким образом, имея:
Причина.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,
new ReasonMetaData(Responsability.Company, false, "Product is not available"));
All.Add(
Reason.PaymentNotDone,
new ReasonMetaData(Responsability.Client, false, "Payment is not done"));
All.Add(
Reason.BlackListedClient,
new ReasonMetaData(Responsability.Client, false, "Client is black listed"));
All.Add(
Reason.NotEnoughTime,
new ReasonMetaData(Responsability.Company, true, "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, Valid = yes, Text = There is not enough stock
ProductNotAvailabe: Responsability = Company, Valid = no, Text = Product is not available
PaymentNotDone: Responsability = Client, Valid = no, Text = Payment is not done
BlackListedClient: Responsability = Client, Valid = no, Text = Client is black listed
NotEnoughTime: Responsability = Company, Valid = yes, Text = There is not enough time
Improvement
Вы можете смешать это решение с атрибутами для автоматического создания списка, проанализировав атрибуты перечисляемых элементов:
Имея:
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, bool valid, string text)
{
Responsability = responsability;
Valid = valid;
Text = text;
}
}
Статический конструктор ReasonMetadata.cs теперь:
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 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, true, "There is not enough stock")]
NotEnoughStock,
// ...
ProductNotAvailabe,
// ...
PaymentNotDone,
// ...
BlackListedClient,
// ...
NotEnoughTime
}