您可以創建一個將兩個或多個對象的動態對象:
class CombineDynamic : DynamicObject
{
private readonly object[] m_objects;
public CombineDynamic(params object[] objects)
{
m_objects = objects;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var callSite = CallSite<Func<CallSite, object, object>>.Create(binder);
foreach (var o in m_objects)
{
try
{
result = callSite.Target(callSite, o);
return true;
}
catch (RuntimeBinderException)
{}
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// the binder from argument uses compile time type from call site,
// which is object here; because of that, setting of properties that
// aren't of type object wouldn't work if we used that binder directly
var fixedBinder = Binder.SetMember(
CSharpBinderFlags.None, binder.Name, typeof(CombineDynamic),
new[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
var callSite =
CallSite<Action<CallSite, object, object>>.Create(fixedBinder);
foreach (var o in m_objects)
{
try
{
callSite.Target(callSite, o, value);
return true;
}
catch (RuntimeBinderException)
{}
}
return base.TrySetMember(binder, value);
}
}
而且使用這樣的:
dynamic viewModel = new CombineDynamic(product, new ExpandoObject());
viewModel.AdditionalProperty = "additional data";
當你或動態設置屬性,它首先試圖做在第一個對象上,然後在第二個對象上,直到它成功。
否則像這樣已經(至少)一個怪異的行爲:如果,例如,Product
有int
物業類型Id
,代碼viewModel.Id = "42";
會成功。但它會在ExpandoObject
上設置屬性。因此,如果您之後嘗試檢索viewModel.Id
,則會從product.Id
返回未修改的int
。
我很可能不會僅僅根據性能做出這樣的決定,但您確定'動態'比使用Automapper快嗎? – svick
這個問題並不是關於性能,而是更輕量,更靈活。一次創建的視圖模型不會超過一百個。 –