我遇到了一个反射问题,我似乎找不到解决方案。
我有以下简单的接口:
public interface IDataProperty<T>
{
public T Value { get; set; }
public int BytesCount();
public byte[] Serialize();
}
实现上面接口的结构体:
public struct IntProperty : IDataPropery<int>
{
private int _value;
public int Value { get => _value; set => _value = value; }
public int BytesCount()
{
return 4;
}
public byte[] Serialize()
{
return BitConverter.GetBytes(_value);
}
public IntDataProperty(int value) { _value = value; }
}
和一个保存值的简单类:
public class ValuesContainer
{
public IntProperty prop1;
public IntProperty prop2;
}
我试图在我的处理器类中调用prop1
和prop2
上的Serialize()
方法,到目前为止还没有运气……:
public class Processor
{
public void ProccesData<T>(out T result) where T : ValuesContainer, new()
{
result = new T();
List<FieldInfo> dataFields = new List<FieldInfo>();
result.GetType().GetFields().ToList().ForEach(field => {
if(field.FieldType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDataProperty<>)))
{
dataFields.Add(field);
}
});
MethodInfo serializeMI = typeof(IDataProperty<>).GetMethod("Serialize");
foreach(FieldInfo field in dataFields)
{
Console.WriteLine(field.Name);
serializeMI.Invoke(field,null);
}
}
}
此时运行代码会产生以下错误:
'Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.'
我知道我需要以某种方式获得field
变量背后的实例,但不知道如何做到这一点。有没有人知道一个好的方法来做我想要实现的使用其他方法,或者只有反射是要走的路,如果后者-我有什么解决方案?
提前感谢大家。
在@JeroenMostert在评论中提供的巨大帮助下,我已经能够从根本上解决问题了。只要Jeroen没有提供一个可以被接受为正确的答案,我就会显示他的解决方案,所以这个问题被标记为已回答。不过,这里的好处还是要归功于@JeroenMostert
internal class Program
{
static void Main(string[] args)
{
ValuesContainer container = new ValuesContainer();
Processor processor = new Processor();
processor.ProccesData(out container);
}
}
public interface IDataProperty<T>
{
public void Serialize();
}
public struct IntProperty : IDataProperty<int>
{
private int _value;
public int Value { get => _value; set => _value = value; }
public int BytesCount()
{
return 4;
}
public void Serialize()
{
Console.WriteLine("I have been invoked !" + this.GetHashCode());
}
}
public class ValuesContainer
{
public IntProperty prop1;
public IntProperty prop2;
}
public class Processor
{
public void ProccesData<T>(out T result) where T : ValuesContainer, new()
{
result = new T();
List<FieldInfo> dataFields = new List<FieldInfo>();
result.GetType().GetFields().ToList().ForEach(field => {
if (field.FieldType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDataProperty<>)))
{
dataFields.Add(field);
}
});
foreach (FieldInfo field in dataFields)
{
Console.WriteLine("Invoking 'Serialize' method on fieldName :" + field.Name);
field.GetValue(result).GetType().GetMethod("Serialize").Invoke(field.GetValue(result), null);
}
}
}