从一组类型为foowriter的类中检索公共属性

时间:2014-03-05 00:11:34

标签: c# reflection

我有一组类,它们都扩展了相同的基类,比如说 fooboo : foowriter, foobar : foowriter。这些具有不同扩展名的所有输出文件,例如fooboo --> .boofoobar --> .bar个文件。

我正在使用反射来获取扩展foowriter的所有具体类型的列表,我需要获取这些类可以生成的所有扩展的列表,即{ ".boo", ".bar" }

目前,每个foowriter都知道它可以生成什么格式,这是在一个只读字段中。我希望将这些知识封装在每个具体类中,而不是在一些额外的类中实现GetOutputExtension<T>() : where T : foowriter方法,因为这会将所有foowriter与额外的实用程序类耦合。

我真的不想实例化具体的类,因为这可能是一个重量级的操作。

从一组类型中获取公共属性而不实例化它们有什么好的模式或方法?

3 个答案:

答案 0 :(得分:3)

一种选择是创建自定义属性。这样,您就可以将扩展与您的类相关联,而无需实例化它们。

用法:

[Output(Extension = ".boo")]
public class fooboo : foowriter { ... }

[Output(Extension = ".bar")]
public class foobar : foowriter { ... }

缺点是在编译时不会强制执行。

编辑但是,您可以为其编写单元测试。

答案 1 :(得分:2)

您可以在基础公共类foowriter上创建静态属性。

然后,您可以在每个子类中覆盖此属性并返回所需的数据。该属性是静态的,因此不需要实例化。

public class foowriter
{
    public static string Extension
    {
        get { throw new NotImplementedException(); }
    }

}

public class foobar
{
    public static string Extension
    {
        get { return "bar"; }
    }

}

public class fooboo
{
    public static string Extension
    {
        get { return "boo"; }
    }

}

答案 2 :(得分:0)

使用反射查找静态属性

使用反射来获取所有具体类:

var type = typeof(foowriter);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(t => type.IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);

然后使用反射来获取您姓名的所有字段值:

var outputFormats = new List<string>();
foreach (var t in types)
{
var prop = t.GetFields().First(i => i.Name == "outputFormat");
    outputFormats.Add(prop.GetValue(null));
}

关于这一点的坏处是它不允许编译时检查。'。没有强制派生类也有outputFormat字段: - /