C#使用Reflection来复制基类属性

Dav*_*vid 26 c# reflection copy

我想使用Reflection将所有属性从MyObject更新到另一个属性.我遇到的问题是特定对象是从基类继承的,并且不更新那些基类属性值.

以下代码复制顶级属性值.

public void Update(MyObject o)
{
    MyObject copyObject = ...

    FieldInfo[] myObjectFields = o.GetType().GetFields(
    BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

    foreach (FieldInfo fi in myObjectFields)
    {
        fi.SetValue(copyObject, fi.GetValue(o));
    }
}
Run Code Online (Sandbox Code Playgroud)

我想看看是否有更多BindingFlags属性我可以用来帮助但无济于事.

mac*_*kow 39

试试这个:

public void Update(MyObject o)
{
    MyObject copyObject = ...
    Type type = o.GetType();
    while (type != null)
    {
        UpdateForType(type, o, copyObject);
        type = type.BaseType;
    }
}

private static void UpdateForType(Type type, MyObject source, MyObject destination)
{
    FieldInfo[] myObjectFields = type.GetFields(
        BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

    foreach (FieldInfo fi in myObjectFields)
    {
        fi.SetValue(destination, fi.GetValue(source));
    }
}
Run Code Online (Sandbox Code Playgroud)


Bog*_*scu 21

我把它写成一个扩展方法,也适用于不同类型.我的问题是我有一些绑定到asp mvc表单的模型,以及映射到数据库的其他实体.理想情况下,我只有1个类,但实体是分阶段构建的,asp mvc模型想要立即验证整个模型.

这是代码:

public static class ObjectExt
{
    public static T1 CopyFrom<T1, T2>(this T1 obj, T2 otherObject)
        where T1: class
        where T2: class
    {
        PropertyInfo[] srcFields = otherObject.GetType().GetProperties(
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);

        PropertyInfo[] destFields = obj.GetType().GetProperties(
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);

        foreach (var property in srcFields) {
            var dest = destFields.FirstOrDefault(x => x.Name == property.Name);
            if (dest != null && dest.CanWrite)
                dest.SetValue(obj, property.GetValue(otherObject, null), null);
        }

        return obj;
    }
}
Run Code Online (Sandbox Code Playgroud)


Aak*_*shM 10

嗯.我想GetFields从链条的各个方向让你的成员,你必须明确指定BindingFlags.DeclaredOnly你是否想要继承的成员.所以我做了一个快速测试,我是对的.

然后我发现了一些东西

我想 使用Reflection 将所有属性从MyObject 更新到另一个属性.我遇到的问题是特定对象是从基类继承的,并且不更新那些基类属性值.

以下代码复制顶级属性值.

public void Update(MyObject o) {
  MyObject copyObject = ...

  FieldInfo[] myObjectFields = o.GetType().GetFields(
  BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
Run Code Online (Sandbox Code Playgroud)

这将只获取字段(包括此类型的私有字段),但不包含属性.所以如果你有这个层次结构(请原谅名字!):

class L0
{
    public int f0;
    private int _p0;
    public int p0
    {
        get { return _p0; }
        set { _p0 = value; }
    }
}

class L1 : L0
{
    public int f1;
    private int _p1;
    public int p1
    {
        get { return _p1; }
        set { _p1 = value; }
    }
}

class L2 : L1
{
    public int f2;
    private int _p2;
    public int p2
    {
        get { return _p2; }
        set { _p2 = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么.GetFieldsL2BindingFlags你指定会得到f0,f1,f2,和_p2,而不是p0p1(这是性能,而不是字段)OR _p0_p1(这是私人的基类,因此类型的对象L2 不具有这些领域.

如果要复制属性,请尝试执行您正在执行的操作,但请.GetProperties改为使用.