使用通用代码从C#中的另一个对象构建对象

使用通用代码从C#中的另一个对象构建对象,c#,entity-framework,generics,reflection,C#,Entity Framework,Generics,Reflection,假设我有一个User类型的对象,如下所示: User { Name = "Bob", Email = "Bob@gmail.com", Class = NULL } 任何人都能想出一种方法来获取该对象并创建如下对象: User { Name = "Bob", Email = "Bob@gmail.com" } public static void CopyProperties(object a, object b) { if (a.GetType() !

假设我有一个User类型的对象,如下所示:

User {
   Name = "Bob",
   Email = "Bob@gmail.com",
   Class = NULL
}
任何人都能想出一种方法来获取该对象并创建如下对象:

User {
   Name = "Bob",
   Email = "Bob@gmail.com"
}
public static void CopyProperties(object a, object b)
{
    if (a.GetType() != b.GetType())
        throw new ArgumentException("Types of object a and b should be the same", "b")

    foreach (PropertyInfo property in a.GetType().GetProperties())
    {
        if (!property.CanRead || !property.CanWrite || (property.GetIndexParameters().Length > 0))
            continue;

        property.SetValue(b, property.GetValue(a, null), null);
    }
}
使用完全通用的代码?也就是说,我不想硬编码与类型或属性有关的任何内容,因为这段代码需要应用于我站点上的每个实体。(顺便说一句,“用户”类型是一个实体,如果它能帮助您更好地编写代码,请使用它)


我只是想为我遇到的一个问题找到一个解决方案,我相信这可能会解决问题,但我需要在不硬编码任何类型或属性的情况下解决这个问题。

这看起来是反射的问题,而不是泛型的问题(尽管泛型可以用作缓存反射策略的一种偷偷摸摸的方式)。除非我读错了,否则您希望创建一个新实例并复制大多数成员。。。哪种反射技术很好,尽管速度相对较慢。您可以通过使用元编程来提高速度;在第一次运行时(每个类型),可能使用DynamicMethod或Expression生成一个优化的版本,并从中存储一个类型化委托。然后使用委托。

泛型在这种情况下帮不了你。实体框架中可能有一些选项,但我对此并不了解

然而,使用反射是可能的。您可以尝试以下方法:

User {
   Name = "Bob",
   Email = "Bob@gmail.com"
}
public static void CopyProperties(object a, object b)
{
    if (a.GetType() != b.GetType())
        throw new ArgumentException("Types of object a and b should be the same", "b")

    foreach (PropertyInfo property in a.GetType().GetProperties())
    {
        if (!property.CanRead || !property.CanWrite || (property.GetIndexParameters().Length > 0))
            continue;

        property.SetValue(b, property.GetValue(a, null), null);
    }
}

请记住,这要求要复制的所有属性都具有公共setter和getter。此外,“深度复制”与“浅层复制”之间也存在差异,这意味着子对象是否也被复制或仅被引用。此示例将仅引用它们,因此它将是“浅拷贝”

使用反射来实现这一点:

public void CopyValues<TSource, TTarget>(TSource source, TTarget target)
{
    var sourceProperties = typeof(TSource).GetProperties().Where(p => p.CanRead);

    foreach (var property in sourceProperties)
    {
        var targetProperty = typeof(TTarget).GetProperty(property.Name);

        if (targetProperty != null && targetProperty.CanWrite && targetProperty.PropertyType.IsAssignableFrom(property.PropertyType))
        {
            var value = property.GetValue(source, null);

            targetProperty.SetValue(target, value, null);
        }
    }
}
public void copyvalue(TSource源、TTarget目标)
{
var sourceProperties=typeof(TSource).GetProperties()。其中(p=>p.CanRead);
foreach(sourceProperties中的var属性)
{
var targetProperty=typeof(TTarget).GetProperty(property.Name);
if(targetProperty!=null&&targetProperty.CanWrite&&targetProperty.PropertyType.IsAssignableFrom(property.PropertyType))
{
var value=property.GetValue(源,空);
SetValue(target,value,null);
}
}
}

这两种用户类型是否不同?不清楚您想做什么。两者的区别在于类字段的存在。您想复制一个对象并删除任何名为“类”的字段,还是想要更一般的字段?底线是你需要做一些反射,它们代表同一个实体。显然,我的实体要复杂得多,但基本上使用存根实体我相信我可以将部分对象保存到数据库中,但我想在保存之前删除任何设置为NULL的值。