具有代码重用的静态类型的泛型反射
本文关键字:静态类 类型 泛型 反射 静态 代码 | 更新日期: 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.";
}