7
votes

Références à Func de différents types

J'ai un singleton qui peut enregistrer une fonction de fonctionnement pour résoudre une valeur d'identification pour chaque type: xxx pré>

par exemple: p>

private Dictionary<Type, Func<object, uint>> _typeMap;


2 commentaires

CAN POST POST et Commentaire Dérive d'une interface commune avec une propriété ID ?


Non, ils ne peuvent pas dériver d'une interface commune.


6 Réponses :


2
votes

Vous avez deux options:

  1. Changement getObjectid à une fonction générique qui prend un t .
    Vous pouvez ensuite Stocker le FUNC S dans un générique Classe statique et appelez-les en écrivant Funcstorage .Value (Obj) .

  2. Utilisez des arbres d'expression à Créer Func s qui appelle le Func (en utilisant une fonte) et mettez ceux-ci dans votre dictionnaire dictionnaire > .
    edit : Vous n'avez pas besoin d'arbres d'expression pour le faire; Vous pouvez utiliser une expression de Lambda normale qui mette à t . 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.


1 commentaires

Merci Slaks, je ne peux pas changer GetObjectid à GetObjectid parce que je ne connais pas le type sur le temps d'exécution.



2
votes

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));
}


0 commentaires

1
votes
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);
        }
    }

1 commentaires

dynamicinvoke 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 ) f; puis retour g (at) . Bien que cela ne fonctionne peut-être pas pour @ EZE1981, cela pourrait fonctionner pour d'autres.



1
votes

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();

    }
}

0 commentaires

0
votes

Je ne peux pas changer getObjectid à getObjectid parce que je ne connaissais pas le type d'exécution.

Donc, j'ai changé la définition du dictionnaire à: xxx

puis l'appelez par réflexion: xxx

Merci à tous tellement


5 commentaires

Regarde ma réponse. Vous pouvez appeler getid sans connaître le type au moment de l'exécution. Il sera déduit.


Vous devez faire le dictionnaire détenir func en faisant une lambda qui jette le paramètre d'objet sur t . 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 ainsi lorsque dictionnaire [typeof (objet) ne pourra rien trouver. En fait depuis que vous avez utilisé dynamicinvoke , vous n'avez pas besoin d'utiliser des génériques du tout sur getid donc dictionnaire [at.getType ())] aurait fait fonctionner, bien que ce soit Soyez lent, de la même manière lente à @ eze1981 de la solution ici depuis dynamicinvoke est juste une coupe courte pour méthode.invoke .



1
votes

@slacks, à la suite de vos conseils, j'ai modifié mon approche de: xxx

merci!


0 commentaires