【发布时间】:2019-08-23 13:23:58
【问题描述】:
我正在尝试编写一段代码,该代码可以获取同一对象的两个实例,并将一些属性从第一个实例动态复制到第二个实例。有点扭曲的是,我只能通过它们都继承的接口访问这些对象。
我创建了一个Copyable 属性,用于标记可以复制哪些属性。
然后我使用PropertyInfo.GetMethod 和PropertyInfo.SetMethod 成功地做到了这一点,但是生成的代码太慢了。与在编译时静态分配属性相比 - 这种方法慢了~20倍。
这是我使用纯反射的初始实现。
using System;
using System.Linq;
namespace ConsoleApp58
{
interface IInterface
{
int Id { get; set; }
}
[AttributeUsage(AttributeTargets.Property)]
class CopyableAttribute : Attribute { }
class Child : IInterface
{
public int Id { get; set; }
[Copyable]
public int CopyableProp { get; set; }
}
class Program
{
static void Main(string[] args)
{
var source = new Child() {Id = 1, CopyableProp = 42};
var target = new Child() {Id = 2, CopyableProp = 0};
CopyProps(source, target);
}
static void CopyProps(IInterface source, IInterface target)
{
var props = target.GetType()
.GetProperties()
.Where(p => p.IsDefined(typeof(CopyableAttribute), false))
.ToArray();
foreach (var prop in props)
{
var value = prop.GetMethod.Invoke(source, new object[] { });
prop.SetMethod.Invoke(target, new [] {value});
}
}
}
}
这可行,但速度很慢,因此我决定尝试创建一个表达式树,该树将构建一个可以调用 getter 和 setter 的 lambda,但我似乎无法让它工作.
我尝试关注this SO question,但是,该实现依赖于这样一个事实,即我知道要从中获取属性的对象的类型是什么。
但是,在我的例子中,属性被定义为子类的一部分,我无法在我的IInterface 中访问它们。
因此,我在这里问。 我是否有一种(快速)方法可以在两个对象的实例之间复制特定属性的值,仅通过它们的公共接口引用它们。
【问题讨论】:
-
我认为从代码中可以清楚地看到。我有两个
IInterface实例,它们都是Child类型。我想从source实例中获取所有具有Copyable属性的属性,并将它们的值复制到target实例中。我想尽快做到这一点 -
第一个实例是反序列化 API 请求后的输入。我需要获取某些属性并将它们复制到另一个实例,该实例包含每个属性的一种“默认”值。第二个实例从原始实例中获取所需的属性,然后传递给其他业务层以供使用。我不能重用同一个实例,因为它稍后会传递给我无法控制的其他组件,并且可能会修改其属性的引用。由于其他不相关的系统细节,我也不能使用具体类型
标签: c# copy expression-trees getter-setter