Bạn có thể sử dụng các thuộc tính để chú thích điều tra và sau đó sử dụng phản chiếu để tạo từ điển.
[AttributeUsage(AttributeTargets.Field)]
sealed class TemplateAttribute : Attribute {
public TemplateAttribute(String fileName) {
FileName = fileName;
}
public String FileName { get; set; }
}
enum EmailTemplate {
[Template("File1.htm")]
WelcomeEmail,
[Template("File2.htm")]
ConfirmEmail
}
class KnownTemplates {
static Dictionary<EmailTemplate, String> knownTemplates;
static KnownTemplates() {
knownTemplates = typeof(EmailTemplates)
.GetFields(BindingFlags.Static | BindingFlags.Public)
.Where(fieldInfo => Attribute.IsDefined(fieldInfo, typeof(TemplateAttribute)))
.Select(
fieldInfo => new {
Value = (EmailTemplate) fieldInfo.GetValue(null),
Template = (TemplateAttribute) Attribute
.GetCustomAttribute(fieldInfo, typeof(TemplateAttribute))
}
)
.ToDictionary(x => x.Value, x => x.Template.FileName);
}
}
Nếu bạn làm điều này rất nhiều bạn có thể tạo một hàm tổng quát tổng quát hơn kết hợp các giá trị liệt kê với một thuộc tính gắn liền với giá trị liệt kê:
static IEnumerable<Tuple<TEnum, TAttribute>> GetEnumAttributes<TEnum, TAttribute>()
where TEnum : struct
where TAttribute : Attribute {
return typeof(TEnum)
.GetFields(BindingFlags.Static | BindingFlags.Public)
.Where(fieldInfo => Attribute.IsDefined(fieldInfo, typeof(TAttribute)))
.Select(
fieldInfo => Tuple.Create(
(TEnum) fieldInfo.GetValue(null),
(TAttribute) Attribute.GetCustomAttribute(fieldInfo, typeof(TAttribute))
)
);
}
Và sử dụng nó như thế này:
knownTemplates = GetEnumAttributes<EmailTemplate, TemplateAttribute>()
.ToDictionary(tuple => tuple.Item1, tuple => tuple.Item2.FileName);
Để có nhiều niềm vui hơn, bạn có thể tạo phương thức mở rộng:
static class EmailTemplateExtensions {
static Dictionary<EmailTemplate, String> templates;
static EmailTemplateExtensions() {
templates = GetEnumAttributes<EmailTemplate, TemplateAttribute>()
.ToDictionary(tuple => tuple.Item1, tuple => tuple.Item2.FileName);
}
public static String FileName(this EmailTemplate emailTemplate) {
String fileName;
if (templates.TryGetValue(emailTemplate, out fileName))
return fileName;
throw new ArgumentException(
String.Format("No template defined for EmailTemplate.{0}.", emailTemplate)
);
}
}
Sau đó, gọi EmailTemplate.ConfirmEmail.FileName()
sẽ trả lại File2.htm
.
Tôi nghĩ rằng họ muốn loại bỏ việc sử dụng lớp học, với cú pháp như 'string sFile = EmailTemplate.Confirm.TemplateFile;'. – AMissico
Martin! Cảm ơn bạn! Thuộc tính là một giải pháp tuyệt vời cho hầu hết các tình huống của tôi (những nơi có chuỗi thích hợp). Tôi biết tôi có trường hợp một đối tượng phức tạp được ánh xạ tới mỗi enum, nhưng điều này thậm chí có thể bao gồm một vài scalars là tốt. – shannon
Điều này trở nên tuyệt vời hơn khi tôi sử dụng nó. Cảm ơn Martin lần nữa. – shannon