具有代码重用的静态类型的通用反射

时间:2011-08-22 15:15:04

标签: c#

我有一个迭代类的字段的方法,将它们的值作为CSV返回。我需要一种方法来以通用的方式为类提供访问权限的方法。

出于某种原因,Statics must derive from object或者您收到编译错误。在这种情况下,从不同的基类派生确实增加了我的代码重用性。还有另一种方法来实现我的目标吗?

我相信我唯一的选择就是让我的静态类成为一个实例类。

//a data container used for Mocking in inversion of control
public class FieldContainer : ReflectionHelper<FieldContainer>
{
    public static string Field1 = "Some Data";
    public static string Field2 = "Persons Name";
    public static string Field3 = "3030 Plane Ave.";
}

    public class ReflectionHelper<T>
    {
    public static string ToCSV()
    {
        StringBuilder fieldCollector = new StringBuilder();

        Type type = typeof(T);
        FieldInfo[] fields = type.GetFields();
        foreach (FieldInfo f in fields)
        {
            fieldCollector.Append(f.GetValue(null) + ",");
        }

        return fieldCollector.ToString();
    }
    }

4 个答案:

答案 0 :(得分:1)

您的代码完全有效(至少在技术上)。您的班级FieldContainer不是static班级,因此可以派生自ReflectionHelper<T>

但是,您通常不会在基类中实现方法ToCSV,因为它基本上可以在任何类上工作。因为您想要处理静态成员,所以扩展方法也不是最好的方法。最简单,最干净的方法是使用一个实现此方法的静态助手类:

public static class ReflectionHelper
{
    public static string ToCSV<T>()
    {
        StringBuilder fieldCollector = new StringBuilder();

        Type type = typeof(T);
        FieldInfo[] fields = type.GetFields();
        foreach (FieldInfo f in fields)
        {
            fieldCollector.Append(f.GetValue(null) + ",");
        }

        return fieldCollector.ToString();
    }
}

你可以像这样使用它:

var csv = ReflectionHelper.ToCSV<FieldContainer>();

然而,我没有看到,为什么你会想要实现这样的东西。它似乎没有多大意义。

答案 1 :(得分:1)

您可以将其形成为扩展方法,如下所示:

public static class ReflectionHelperExtensions
{
    public static string ToCSV<T>(this T instance)
    {
        var type = instance.GetType();
        var fields = type.GetFields();
        var fieldCollector = new StringBuilder();        
        foreach (FieldInfo f in fields)
        {
            fieldCollector.Append(f.GetValue(null) + ",");
        }
        return fieldCollector.ToString();
    }
}

这样,您的字段容器类不需要从任何给定类型派生,因为这适用于object的所有派生。

答案 2 :(得分:0)

您是否使用扩展方法进行了结论?

public static class ReflectionExtensions
{
     public static string ToCSV(this object input)
     { 
         StringBuilder fieldCollector = new StringBuilder();

         Type type = input.GetType();
         FieldInfo[] fields = type.GetFields();
         foreach (FieldInfo f in fields)
         {
             fieldCollector.Append(f.GetValue(null) + ",");
         }

         return fieldCollector.ToString();
    }
}

然后你可以在任何对象上调用以下内容:

FieldContainer c = new FieldContainer();
string result = c.ToCSV();

答案 3 :(得分:0)

如果您将该类作为实例类型,则可以。

public abstract class ReflectionHelper<T>
{
    protected ReflectionHelper()
    { }


    public static string ToCsv(string delimiter = ",")
    {
        var fieldCollector = new StringBuilder();

        var type = typeof(T);
        var fields = type.GetFields();
        foreach (var f in fields)
        {
            fieldCollector.Append(f.GetValue(null) + delimiter);
        }

        return fieldCollector.ToString();
    }
}

public class Something : ReflectionHelper<Something>
{
    protected Something() : base()
    {

    }
    public static string Field1 = "Some Data";
    public static string Field2 = "Persons Name";
    public static string Field3 = "3030 Plane Ave.";
}
相关问题