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

本文关键字:静态类 类型 泛型 反射 静态 代码 | 更新日期: 2023-09-27 18:06:15

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

由于某些原因,静态对象必须派生自对象,否则会出现编译错误。在这种情况下,从不同的基类派生确实增加了代码的可重用性。有没有别的方法可以实现我的目标?

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

//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();
    }
    }

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

您的代码是完全有效的(至少在技术上)。你的类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>();

然而,我不明白,为什么你想要实现这样的东西。这似乎不太有意义。

您可以将它形成一个扩展方法,如下:

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的所有派生。

您考虑过使用扩展方法吗?

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

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

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.";
}