J'ai un singleton qui peut enregistrer une fonction de fonctionnement pour résoudre une valeur d'identification pour chaque type: par exemple: p> private Dictionary<Type, Func<object, uint>> _typeMap;
6 Réponses :
Vous avez deux options: p>
Changement getObjectid code> à une fonction générique qui prend un
t code>.
Vous pouvez ensuite Stocker le FUNC
et appelez-les en écrivant Funcstorage
Func
Func
edit strong>: Vous n'avez pas besoin d'arbres d'expression pour le faire; Vous pouvez utiliser une expression de Lambda normale qui mette à t code>. Je pensais à l'affaire inverse (générant un délégué générique d'un non générique), qui nécessite des arbres d'expression. P> li>
ol>
Merci Slaks, je ne peux pas changer GetObjectid à GetObjectid
Vous n'avez pas besoin d'arbres d'expression pour le faire comme vous le suggérez, il suffit de nier la fonction lorsque vous l'enregistrez.
public void RegisterType<T>(Func<T, uint> func){ _typeMap.Add(typeof(T), obj=>func((T)obj)); }
public class Registration { public static Registration Instance = new Registration(); private Registration() { } private Dictionary<Type, object> Dictionary = new Dictionary<Type, object>(); public void Register<T>(Func<T, uint> aFunc) { Dictionary[typeof(T)] = aFunc; } public uint GetId<T>(T aT) { var f = Dictionary[typeof(T)]; var g = (Delegate)f; return (uint) g.DynamicInvoke(aT); } }
dynamicinvoke code> est lent mais dans la solution de @ Pedro, il n'est pas nécessaire. Le type peut réellement être connu dans cet exemple de telle sorte que
var g = (func
retour g (at) code>. Bien que cela ne fonctionne peut-être pas pour @ EZE1981, cela pourrait fonctionner pour d'autres.
Le problème est que chaque func a un TYPE DIFERENT T, et je ne peux pas faire quelque chose comme ceux-ci: p>
class Program { private static Dictionary<Type, Func<object, uint>> _typeMap = new Dictionary<Type, Func<object, uint>>(); static void Main(string[] args) { RegisterType<Post>(p => p.PostId); Post myPost = new Post(); myPost.PostId = 4; var i = GetObjectId(myPost); Console.WriteLine(i); Console.ReadKey(); } }
Je ne peux pas changer Donc, j'ai changé la définition du dictionnaire à: p> puis l'appelez par réflexion: p> Merci à tous tellement p> p> getObjectid code> à
getObjectid
Regarde ma réponse. Vous pouvez appeler getid
Vous devez faire le dictionnaire détenir func
t code>. Ce sera beaucoup plus rapide.
@Petro: mal. L'inférence de type ne peut se produire qu'à la compilation.
@Slaks Oui, l'inférence survient à la compilation. Mais regardez mon code. Ça va marcher.
@Pedro L'inférence au moment de la compilation sera getid
dictionnaire [typeof (objet) code> ne pourra rien trouver. En fait depuis que vous avez utilisé
dynamicinvoke code>, vous n'avez pas besoin d'utiliser des génériques du tout sur getid donc
dictionnaire [at.getType ())] code> aurait fait fonctionner, bien que ce soit Soyez lent, de la même manière lente à @ eze1981 de la solution ici depuis
dynamicinvoke code> est juste une coupe courte pour
méthode.invoke code>.
@slacks, à la suite de vos conseils, j'ai modifié mon approche de: merci! p> p>
CAN
POST POST CODE> et
Commentaire CODE> Dérive d'une interface commune avec une propriété
ID code>?
Non, ils ne peuvent pas dériver d'une interface commune.