실버 눈금에 표시 할 (동적으로 생성 된 형식) 컬렉션을 만드는 중 하나는 가져 오기 (동적 생성 된 형식) 형식을 만든 다음 가져 오기 형식의 속성을 의 컬렉션 (동적으로 생성 된 타입) 두 가지 유형의 항목을 식별하는 Id 속성을 공유하는 그리드Object to Object 컬렉션의 속성 매핑
int Id {get; set}
string Foo {get;set;}
string FooFoo {get;set;}
에 바인딩
즉 유형 (그리드 또는 가져 오기에이를 수)와 유형을 가져
int Id {get; set}
string Foo {get;set}
여기서 ids가 일치합니다. 나는 foos를 복사하려고합니다.
컬렉션의 한 유형에서 다른 유형으로 속성을 빠르게 매핑하는 방법은 무엇입니까?
편집
을 heres keymembers이 동일 할 때 기능은, 멤버 이름, 작품을 대표하는 사전 문자열 문자열을 통해 정의 된 매핑을 두 가지 유형의지도를하므로 스테판 덕분에 최종 Typemapper 구현 실버 라이트. 한 항목에서 다른 속성을 매핑합니다
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);
}
}
할 수 있어야, 그것은 (반사를 사용하여) 우리가 때 느린 것으로 판명 약간의 1000s를 고려하십시오. 여전히 +1 –
유형이 동적으로 생성되는 경우 이것이 가장 가능성이 높습니다. 'Reflection.Emit'을 사용하여 팩토리 델리게이트를 생성 한 다음 실행하면 속도를 약간 높일 수 있습니다.하지만 정확히 할 경로는 확실하지 않습니다. 'Reflection.Emit'을 위해 MSDN을 살펴 보는 것이 좋습니다. 좋은 방향을 제시 할 수 있기 때문입니다. – Stephan
이것은 Silverlight 질문 이었음을 잊었습니다. 내 두 번째 솔루션은 Silverlight에서 아마 작동하지 않을 것입니다. RIA와 마찬가지로 서버 측 작업으로도 가능하지만 순수 클라이언트 측으로는 작동하지 않을 수 있습니다. – Stephan