用于在 C# 中检索属性的类型化包装器

本文关键字:类型化 包装 属性 检索 用于 | 更新日期: 2023-09-27 18:35:19

有一个自定义属性,允许声明用于序列化某个类的文件的扩展名:

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class FileExtensionAttribute : Attribute {  
  readonly string extension;
  readonly string description;
  public FileExtensionAttribute(string extension, string description) {
    this.extension = extension;
    this.description = description;
  }
  public string Extension { get { return extension; } }
  public string Description { get { return description; } }
  public string GetFilterString() { return string.Format("{0}|*.{1}", description, extension); }
}

我用它标记了一些类:

[FileExtension("users", "Contestants DB")]
public class UsersDB {
  //...
}

所以现在我使用反射来检索GetFilterString()结果:

string filter = (Attribute.GetCustomAttribute(typeof(UsersDB), typeof(FileExtensionAttribute)) as FileExtensionAttribute).GetFilterString();
saveFileDialog.Filter = filter;
openFileDialog.Filter = filter;

我想写得更有表现力,少一些冗长的东西,像这样:

UsersDB.Attributes.FileExtension.GetFilterString();

或至少

AttributesOf(UsersDB).FileExtension.GetFilterString();

我希望这种语法适用于任何属性和类。

用于在 C# 中检索属性的类型化包装器

你可以

像这样扩展对象

static class ObjectExtends
{
    public static T GetAttribute<T>(this object obj) where T : Attribute
    {
        return (T)Attribute.GetCustomAttribute(obj.GetType(), typeof(T));
    }
    public static T GetAttribute<T>(Type t) where T : Attribute
    {
        return (T)Attribute.GetCustomAttribute(t, typeof(T));
    }
}

用法:

string s = "Hello World";
s.GetAttribute<SomeAttribute>();

ObjectExtends.GetAttribute<SomeAttribute>(typeof(SomeClass));