假设我有类型用户的对象,如下所示:
User {
Name = "Bob",
Email = "Bob@gmail.com",
Class = NULL
}
任何人都可以想到一种方法来获取该对象并创建一个这样的对象:
User {
Name = "Bob",
Email = "Bob@gmail.com"
}
使用完全通用的代码?这意味着,我不想硬编码任何与Type或Properties相关的代码,因为这段代码需要应用于我网站上的每个实体。 (顺便说一句,“用户”类型是一个实体,所以如果它能帮助你更好地编码,请使用它)。
我只想尝试解决我遇到的问题并且我相信Stub Entities可以解决问题,但我需要在不对任何类型或属性进行硬编码的情况下进行解决。
答案 0 :(得分:5)
使用反射来实现这一目标:
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);
}
}
}
答案 1 :(得分:4)
对于这种情况,泛型不会帮助你。实体框架中可能有一些选项,但我并不知道。
然而,可以使用Reflection。你可以尝试这样的事情:
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);
}
}
请注意,这需要您要复制的所有属性同时具有公共设置器和getter。 “深拷贝”与“浅拷贝”之间也存在差异,这意味着子对象也被复制或仅被引用。这个例子只会引用它们,因此它将是一个“浅拷贝”
答案 2 :(得分:2)
这看起来像是反思而不是泛型的问题(尽管泛型可以用作缓存反射策略的偷偷摸摸的方式)。除非我误读它,否则你想要创建一个新实例并复制大多数成员......哪种反射很擅长,尽管相对较慢。您可以使用元编程来提高速度;在第一次运行时(每个类型)生成一个优化版本,可能使用DynamicMethod或Expression,并存储一个类型化的委托。然后只需使用委托。