【问题标题】:Generic Reflection of static types with code reuse具有代码重用的静态类型的通用反射
【发布时间】:2011-08-22 15:15:03
【问题描述】:

我有一个迭代类的字段的方法,将它们的值作为 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();
    }
    }

【问题讨论】:

  • 你为什么要这样 - 这很臭。
  • @Daniel A. White - 哪个部分有代码味道?反射部分、CSV转换、Field容器……?
  • 也许“代码味道”是因为这些类有点不寻常,因为它们的唯一目的是帮助我模拟我的数据库。我在 MVC 中实现 ViewModel,这些 Mock 类有助于使用 Ninject 设置 IoC。我使用字符串和字符串 [] 让我的 ViewModel 保持简单。这些类让我可以定义简单的模型来填充所说的 ViewModel,而无需使用文本数据和通过 XML 强类型构造复杂类型。

标签: c#


【解决方案1】:

您的代码完全有效(至少在技术上如此)。您的类 FieldContainer 不是 static 类,因此它可以派生自 ReflectionHelper&lt;T&gt;

但是,您通常不会在基类中实现方法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>();

但是,我不明白,为什么你会想要实现这样的东西。这似乎没有太多意义。

【讨论】:

  • 我最初的选择是扩展方法,但我在使用静态时遇到了类似的问题。如果转换为实例方法是最好的选择,那么扩展就会重新发挥作用。我只是有点犹豫,因为这个 Class 只是一个静态字段的列表。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      如果你将类作为实例类型就可以了。

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

      【讨论】:

        猜你喜欢
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-30
        • 2011-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多