2016-08-15 3 views
1

J'ai un constructeur pour une classe qui ressemble à ceci:Comment passer un Func <dans T1, dans T2, dans T3, sur TResult> vers un constructeur?

public class Class 
{ 
private Func<string, IThirdField, IFourthField, IResultField> resultField; 

public Class(
     IFirstField firstField, 
     ISecondField secondField, 
     Func<string, IThirdField, IFourthField, IResultField> resultField, 
     ISomeOtherField someOtherField) 
} 

Je suis en train d'initialiser cette classe comme ceci:

var classObject = new Class (firstField, secondField, 
Func<string, IThirdField, IFourthField, IResultField> 
resultField, someOtherField); 

Je reçois les erreurs suivantes:

  • L'utilisation du type générique 'Func' nécessite 1 type d'arguments.

  • Terme d'expression invalide "chaîne". "IThirdField" est un type qui n'est pas valide dans le contexte donné.

Qu'est-ce que je fais mal?

+0

Avez-vous déjà une méthode avec la signature nécessaire? Quelque chose comme: 'IResultField doStuff (valeur de chaîne, IThirdField thirdField, IFourthField fourthField) {/ * ... * /}'? Ou voulez-vous passer dans une méthode anonyme "à la volée"? – Corak

+0

@ M.Tach - Est-ce que l'une des réponses ci-dessous vous a aidé à résoudre le problème? –

+0

Non, j'ai fini par coder en dur une méthode d'assistance pour retourner un objet de type IResultField. –

Répondre

2

Vous devez passer une instance qui répond à cette signature du Func si:

var obj = new Class (firstField, 
        secondField, 
        (stringVal, thirdFieldVal, fourthFieldVal) => default(IResultField), 
        someOtherField); 

Ou si vous avez une fonction nommée alors:

var obj= new Class (firstField, 
        secondField, 
        /*your named function*/), 
        someOtherField); 
+1

Autant que je sache, ces deux options passent cinq arguments au constructeur, qui ne prend que quatre arguments. Comment compile-t-il? –

0

Vous devez transmettre le Func<>

var classObject = new Class (firstField, secondField, 
(stringVal, thirdFieldVal, fourthFieldVal) => { 
    // do something here 

    return something;// where something is of type IResultField 
}, 
someOtherField); 

Le passage Func<> est un bon moyen de bien ce que vous voulez arriver avec l'entrée particulière, mais pas au moment où vous lui donnez cette définition de méthode et si vous voulez des résultats différents en utilisant différentes implémentations.

Linq est un bon exemple. Vous pouvez utiliser Where<T>(Func<T, bool> predicate) et lui donner une définition de ce que vous souhaitez exécuter au moment où Where doit l'utiliser (c'est-à-dire dans les différentes itérations). Cela rend donc l'exécution de la fonction différée (bien que cela vous soit laissé).

Il me semble, que vous passez dans les paramètres de ce Func<> dans le constructeur et donne également une définition de la méthode que vous souhaitez exécuter en utilisant ces paramètres. Pour moi, cela ne semble pas être la meilleure solution.

Dans votre exemple, il vaudrait mieux simplement définir l'interface avec une signature de méthode, puis définir plusieurs implémentations. Il me semble que vous essayez d'y parvenir grâce à l'utilisation d'un Func<>

+0

+1 Vous n'avez pas à passer un lambda, si vous avez une méthode qui correspond à la signature, vous pouvez transmettre cette méthode soit (juste le nom, n'appelez pas la méthode). –

+0

Autant que je sache, cela passe cinq arguments au constructeur, qui ne prend que quatre arguments. Comment compile-t-il? –

+0

@MarkSeemann ouais fixé cela. Cela ressemble plus à un exemple artificiel de ce que l'utilisateur est en train de faire, ce qui n'a pas vraiment de sens pour moi –

1

Vous devrez passer un délégué. Il existe différentes façons de le faire, mais en passant une fonction anonyme peut être le plus facile:

var classObject = 
    new Class(
     firstField, 
     secondField, 
     (str, thrd, frth) => new ResultFieldImp()), 
     someOtherField); 

Ici, je suppose que ResultFieldImp implémente IResultField. Vous devez probablement modifier cette étape pour faire ce qui est réellement nécessaire.

+0

Hi @Mark. S'il vous plaît pensez-vous que vous pourriez prendre à regarder une question? http://stackoverflow.com/questions/40198294/how-to-configure-ninject-so-that-it-creates-a-single-instance-per-controller?noredirect=1#comment67673663_40198294 – eddy

+0

@eddy Je n'ai jamais NInject utilisé, donc je ne peux pas vous aider. Pardon. –

+0

Pas de problème @Mark. Merci quand même. – eddy