Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将类属性从类复制到新的子类C#_C#_Reflection_Properties - Fatal编程技术网

将类属性从类复制到新的子类C#

将类属性从类复制到新的子类C#,c#,reflection,properties,C#,Reflection,Properties,我有一个基础班 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ClassPropertyTest { public class BaseClass { public string name { get; set; } public double value { get; set; } } }

我有一个基础班

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class BaseClass
    {
        public string name { get; set; }
        public double value { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class ClassA : BaseClass
    {
    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class ClassB : BaseClass
    {
    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class ClassC : BaseClass
    {
    }

}
然后我有一个从基类派生的类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class BaseClass
    {
        public string name { get; set; }
        public double value { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class ClassA : BaseClass
    {
    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class ClassB : BaseClass
    {
    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class ClassC : BaseClass
    {
    }

}
我还有一个masterclass,它具有每个类实例的属性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPropertyTest
{
    public class MasterClass
    {
        public ClassA ClassA { get; set; }
        public ClassB ClassB { get; set; }
        public ClassC ClassC { get; set; }
    }
}
现在,当我收到masterclass的实例时,我需要从属性ClassA创建一个新类。我使用反射,但我不断得到错误,目标是无效的

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ClassPropertyTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //Fill master class
            MasterClass o_masterclass = new MasterClass();
            o_masterclass.ClassA = new ClassA { name = "classA", value = 1 };
            o_masterclass.ClassB = new ClassB { name = "classB", value = 2 };
            o_masterclass.ClassC = new ClassC { name = "classc", value = 3 };



            //Now get class by property name
            foreach (PropertyInfo prop in o_masterclass.GetType().GetProperties())
            {
                //Check for class A property
                if (prop.Name == "ClassA") {
                    //Create an instance of that type from ClassA
                    BaseClass instance = (BaseClass)Activator.CreateInstance(prop.PropertyType.BaseType);
                    //Copy properties from masterclass property ClassA to new instance of BaseClass
                    CopyObject<BaseClass>(prop.PropertyType.BaseType, ref instance);
                }
            }
            Console.ReadKey();
        }

        /// <summary>
        /// Copy an object to destination object, only matching fields will be copied
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sourceObject">An object with matching fields of the destination object</param>
        /// <param name="destObject">Destination object, must already be created</param>
        public static void CopyObject<T>(Type sourceObject, ref T destObject)
        {
            //  If either the source, or destination is null, return
            if (sourceObject == null || destObject == null)
                return;

            //  Get the type of each object
            Type sourceType = sourceObject;//.GetType();
            Type targetType = destObject.GetType();

            //  Loop through the source properties
            foreach (PropertyInfo p in sourceType.GetProperties())
            {
                //  Get the matching property in the destination object
                PropertyInfo targetObj = targetType.GetProperty(p.Name);
                //  If there is none, skip
                if (targetObj == null)
                    continue;

                //  Set the value in the destination
                targetObj.SetValue(destObject, p.GetValue(sourceObject, null), null);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
运用系统反思;
命名空间类属性测试
{
班级计划
{
静态void Main(字符串[]参数)
{
//补习硕士班
MasterClass o_MasterClass=新的MasterClass();
o_masterclass.ClassA=newclassa{name=“ClassA”,value=1};
o_masterclass.ClassB=newclassb{name=“ClassB”,value=2};
o_masterclass.ClassC=newclassc{name=“ClassC”,value=3};
//现在按属性名获取类
foreach(o_masterclass.GetType().GetProperties()中的PropertyInfo属性)
{
//检查A类属性
如果(prop.Name==“ClassA”){
//从ClassA创建该类型的实例
基类实例=(基类)Activator.CreateInstance(prop.PropertyType.BaseType);
//将属性从masterclass属性ClassA复制到基类的新实例
CopyObject(prop.PropertyType.BaseType,ref实例);
}
}
Console.ReadKey();
}
/// 
///将对象复制到目标对象,仅复制匹配的字段
/// 
/// 
///具有目标对象的匹配字段的对象
///必须已创建目标对象
公共静态void CopyObject(类型sourceObject,ref T destObject)
{
//如果源或目标为空,则返回
if(sourceObject==null | | destObject==null)
返回;
//获取每个对象的类型
类型sourceType=sourceObject;//.GetType();
类型targetType=destObject.GetType();
//循环查看源属性
foreach(sourceType.GetProperties()中的PropertyInfo p)
{
//获取目标对象中的匹配属性
PropertyInfo targetObj=targetType.GetProperty(p.Name);
//如果没有,跳过
if(targetObj==null)
继续;
//设置目标中的值
targetObj.SetValue(destObject,p.GetValue(sourceObject,null),null);
}
}
}
}
有人能帮我吗?谢谢

@Sergey,我已将CopyObject方法更改为:

  public static void CopyObject<T>(T sourceObject, ref T destObject)
        {
            //  If either the source, or destination is null, return
            if (sourceObject == null || destObject == null)
                return;

            //  Get the type of each object
            Type sourceType = sourceObject.GetType();
            Type targetType = destObject.GetType();

            //  Loop through the source properties
            foreach (PropertyInfo p in sourceType.GetProperties())
            {
                //  Get the matching property in the destination object
                PropertyInfo targetObj = targetType.GetProperty(p.Name);
                //  If there is none, skip
                if (targetObj == null)
                    continue;

                //  Set the value in the destination
                targetObj.SetValue(destObject, p.GetValue(sourceObject, null), null);
            }
        }
公共静态void CopyObject(T sourceObject,ref T destObject)
{
//如果源或目标为空,则返回
if(sourceObject==null | | destObject==null)
返回;
//获取每个对象的类型
类型sourceType=sourceObject.GetType();
类型targetType=destObject.GetType();
//循环查看源属性
foreach(sourceType.GetProperties()中的PropertyInfo p)
{
//获取目标对象中的匹配属性
PropertyInfo targetObj=targetType.GetProperty(p.Name);
//如果没有,跳过
if(targetObj==null)
继续;
//设置目标中的值
targetObj.SetValue(destObject,p.GetValue(sourceObject,null),null);
}
}
当我像你告诉我的那样叫它的时候

 CopyObject<BaseClass>(o_masterclass.ClassA, ref instance);
CopyObject(o_masterclass.ClassA,ref实例);
但在我的情况下,o_masterclass.ClassA实际上是prop.PropertyType.BaseType。如何将此类型转换为所需对象?

您可以使用该类型(或其他映射库):

var otherA=Mapper.Map(o_masterclass.ClassA);
默认情况下,它按名称映射属性。因此,在这种情况下,您甚至不需要设置任何配置

在解决方案中,应传递sourceObject,而不是其类型:

public static void CopyObject<T>(T sourceObject, ref T destObject)
{            
    if (sourceObject == null || destObject == null)
        return;

    //  Get the type of each object
    Type sourceType = sourceObject.GetType();
    Type targetType = destObject.GetType();

    //  Loop through the source properties
    foreach (PropertyInfo sourceProp in sourceType.GetProperties())
    {
        //  Get the matching property in the destination object
        PropertyInfo destProp = targetType.GetProperty(sourceProp.Name);
        //  If there is none, skip
        if (destProp == null)
            continue;

        //  Set the value in the destination
        object value = sourceProp.GetValue(sourceObject, null);
        destProp.SetValue(destObject, value, null);
    }
}
公共静态void CopyObject(T sourceObject,ref T destObject)
{            
if(sourceObject==null | | destObject==null)
返回;
//获取每个对象的类型
类型sourceType=sourceObject.GetType();
类型targetType=destObject.GetType();
//循环查看源属性
foreach(sourceType.GetProperties()中的PropertyInfo sourceProp)
{
//获取目标对象中的匹配属性
PropertyInfo destProp=targetType.GetProperty(sourceProp.Name);
//如果没有,跳过
如果(destProp==null)
继续;
//设置目标中的值
object value=sourceProp.GetValue(sourceObject,null);
destProp.SetValue(destObject,value,null);
}
}
这样说吧:

CopyObject<BaseClass>(o_masterclass.ClassA, ref instance);
CopyObject(o_masterclass.ClassA,ref实例);

还要记住,类型可以包含索引器或只读属性。

但为什么它不起作用?我制作了一个控制台应用程序来测试它,在我的例子中,使用不同的类名和属性可以工作。它在这一行崩溃//设置目标targetObj.SetValue(destObject,p.GetValue(sourceObject,null),null)中的值;出现错误:TargetException为unhandled@Sergey,Automapper确实可以工作,但是我需要通过字符串选择need属性'ClassA'。这也可以是“ClassB”或“ClassC”。我想成为泛型。@Alex刚刚验证过-它确实映射了示例基类的所有属性。你们有我答案最后一行中指定的属性吗