我有一个接受泛型类型T的泛型方法。我知道在运行时T将是我之前定义的一组结构中的某种类型的结构。我无法弄清楚如何实例化结构并初始化结构的字段。
public void mymethod<T>() {
// T is a struct which I know will have certain fields.
// I want to initialize them in this method
Type type = typeof(T);
System.Reflection.MemberInfo attributes = typeof(T);
//which line is correct, top one or one below?
//System.Reflection.MemberInfo attributes = typeof(T).GetMember("length", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)[0];
}
我是否需要为我知道的每个字段分配一个MemberInfo对象?或者是否可以只获取传入结构的所有字段(因为我知道不同的结构将具有其他人不具备的某些不同的字段)。此外,一旦我有一个字段,我该如何为该特定结构赋值?
只是为了让问题更清楚:我想要完成的是以下内容。我确信在运行时my_method将接受我在另一个类中定义的一组结构中的某种结构。以下是其中两个结构的示例:
public struct Struct1 {
public int length;
public int width;
}
public struct Struct2 {
public int length;
public int width;
public int height;
public string color;
}
mymethod()将接受一个通用结构作为T.我想根据我在mymethod中进行的计算将字段分配给该结构(这是无关紧要的,所以我没有在这里显示它们)。每个结构都有一些基本字段(例如在上面的示例中,Struct1和Struct2都有长度和宽度,但Struct2有更多属性)。对于以T形式传递的结构,我想为其字段赋值。因此,例如,如果将Struct2传入T,那么我想说
struct2.length = 1;
struct2.width = 2;
struct2.height;
struct2.color;
我需要找到执行上述操作的通用等价物,所以我尝试使用MemberInfo来实现这一点。我的问题是如何至少分配传入的任何结构的基本字段?我知道,如果我说Struct2 struct2 = new Struct2(
)那么所有的属性都被初始化了但我真的不能说typeof(T) somestruct = new typeof(T)
那么,我是否需要为每个可能与否的字段初始化MemberInfo对象在那儿?我不认为这会有效,因为不同的结构会有不同的领域。如果有一种方法可以获取结构的所有字段,将它们初始化为某个基本值(例如当您说Struct2 struct2 = new Struct2()时所执行的操作),然后将实际值分配给结构我知道会在那里。如何将字段分配给通用对象?
答案 0 :(得分:0)
以下内容将遍历原始结构中的所有字段,如果存在于新目标结构实例上,则会映射它们。
void Main()
{
var instance = MyMethod<Struct1, Struct2>(new Struct1() { length = 1, width = 2});
}
public TTo MyMethod<TFrom, TTo>(TFrom fromStruct)
{
var toType = typeof(TTo);
var instance = Activator.CreateInstance<TTo>();
foreach (var fromField in fromStruct.GetType().GetFields())
{
var toField = instance.GetType().GetField(
fromField.Name, BindingFlags.Public | BindingFlags.Instance);
if (toField != null)
{
var value = fromField.GetValue(fromStruct);
TypedReference reference = __makeref(instance);
toField.SetValueDirect(reference, value);
}
}
return instance;
}
现在说,虽然这有效但你不应该这样做!这是通过未记录的__makeref方法改变结构(感谢this answer)。如果你想以这种方式从一个实例复制到另一个实例,你真的应该使用具有公共属性的类。