La création d'une collection de (type générée dynamiquement) à afficher dans une grille Silverlight et l'un des processus implique la création d'un type d'importation (type généré dynamiquement) puis le mappage des propriétés sur le type d'importation. la collection de (type généré dynamiquement), les deux types partagent une propriété ID qui identifie le produit (que ce soit sur la grille ou dans l'importation)Mappage de l'objet à l'objet dans les collections
-à-dire le type lié à la grille
int Id {get; set}
string Foo {get;set;}
string FooFoo {get;set;}
et importer le type
int Id {get; set}
string Foo {get;set}
où ids correspond je veux copier foos.
Qu'est-ce qu'un moyen rapide de mapper des propriétés d'un type à un autre dans une collection?
EDIT
Heres la mise en œuvre de Typemapper finale avec grâce à Stephan, en tant que caractéristique ne carte les deux types lorsque les keymembers sont égaux, les correspondances définies par une chaîne de chaîne dictionnaire représentant les noms de membres, travaux en 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);
}
}
je l'ai fait quelque chose de tout à fait similaire, il se révèle être lente (par réflexion) lorsque nous sommes compte tenu de quelques milliers. encore +1 –
Si les types sont générés dynamiquement, c'est probablement ce que vous ferez de mieux. Vous faites en sorte de l'accélérer un peu en utilisant 'Reflection.Emit' pour générer un délégué d'usine et en l'exécutant, mais je ne suis pas sûr du chemin exact pour le faire. Vous pouvez jeter un oeil au MSDN pour 'Reflection.Emit' car il pourrait donner une bonne direction. – Stephan
J'ai oublié que c'était une question Silverlight. Ma deuxième solution ne fonctionnera probablement pas pour Silverlight. Il serait possible de le faire comme une opération côté serveur (comme avec RIA), mais comme un côté purement client, il ne fonctionnera probablement pas. – Stephan