我創建了一個用於在Silverlight網格中顯示的(動態生成類型)的集合,其中一個過程涉及創建一個導入(動態生成類型)類型,然後將導入類型的屬性映射到的集合(動態生成的類型)這兩種類型的共享標識項的Id屬性(無論是在網格上或在導入)對象到對象集合中的屬性映射
即 類型結合到電網
int Id {get; set}
string Foo {get;set;}
string FooFoo {get;set;}
和導入類型
int Id {get; set}
string Foo {get;set}
其中ids匹配我想複製foos。
將屬性從一種類型映射到另一種類型的快速方法是什麼?
編輯
繼承人的最終Typemapper實現與感謝斯蒂芬,因爲當keymembers相等功能只會在兩種類型的映射,表示成員的名字,作品通過字典串串定義的映射在silverlight。
public class TypeMapper
{
private readonly DynamicMethod _mapper;
public static DynamicMethod BuildMapper(Type fromType,
Type toType,
KeyValuePair<string, string> keyMemberMap,
Dictionary<string, string> memberMappings)
{
var method = new DynamicMethod("Map", typeof(bool), new[] { fromType, toType });
// Preparing Reflection instances
MethodInfo getFromKeyMethod = fromType.GetMethod(
string.Format("get_{0}", keyMemberMap.Key),
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo getToKeyMethod = toType.GetMethod(
string.Format("get_{0}", keyMemberMap.Value),
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
ILGenerator gen = method.GetILGenerator();
// Preparing locals
gen.DeclareLocal(typeof(Boolean));
// Preparing labels
Label labelNoMatch = gen.DefineLabel();
// Writing body
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Callvirt, getFromKeyMethod);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Callvirt, getToKeyMethod);
gen.Emit(OpCodes.Ceq);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Brfalse_S, labelNoMatch);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Ldarg_0);
foreach (var mapping in memberMappings)
{
var getFromValueMethod = fromType.GetMethod(
string.Format("get_{0}", mapping.Key),
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var setToValueMethod = toType.GetMethod(
string.Format("set_{0}", mapping.Value),
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
gen.Emit(OpCodes.Callvirt, getFromValueMethod);
gen.Emit(OpCodes.Callvirt, setToValueMethod);
}
gen.MarkLabel(labelNoMatch);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ret);
return method;
}
public void Map (object fromInstance, object toInstance)
{
_mapper.Invoke(null, new[] { fromInstance, toInstance });
}
public TypeMapper(Type fromType, Type toType,
KeyValuePair<string, string> keyMemberMap,
Dictionary<string, string> memberMappings)
{
_mapper = BuildMapper(fromType, toType, keyMemberMap, memberMappings);
}
}
我做了一件很相似,它原來是緩慢的(使用反射)當我們考慮幾千年。仍然+1 – 2010-06-24 15:09:14
如果這些類型是動態生成的,這可能是您要做的最好的。你可以通過使用Reflection.Emit來生成一個工廠委託,然後運行它,但是我不確定這樣做的確切路徑。你可能想看一下MSDN的'Reflection.Emit',因爲它可以給出一個好的方向。 – Stephan 2010-06-24 17:53:47
忘記了這是一個Silverlight問題。我的第二個解決方案可能不適用於Silverlight。這可能會作爲服務器端操作(與RIA一樣),但作爲純粹的客戶端,它可能無法工作。 – Stephan 2010-06-24 20:16:32