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

时间:2014-12-23 23:51:21

标签: c# attributes extension-methods

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

[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();

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

1 个答案:

答案 0 :(得分:2)

您可以像这样扩展对象

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));