2009-05-27 8 views
4

Disons que j'ai une interface IMyInterface<T> qui décrit simplement une fonction:conversion implicite à Func

public interface IMyInterface<T> 
{ 
    T MyFunction(T item); 
} 

je pouvais remplacer à ce sujet avec Func<T, T>, mais je veux l'interface pour des raisons sémantiques. Puis-je définir une conversion implicite entre cette interface et Func<T,T> de sorte que je puisse passer un délégué anonyme ou lambda en tant qu'argument à une fonction qui accepte cette interface en tant que paramètre, exactement comme si j'avais utilisé Func<T,T> à la place?

Pour démontrer, en utilisant l'interface déclarée ci-dessus, je veux une fonction comme ceci:

public T TestFunction<T>(IMyInterface myInterface, T value) 
{ 
    return myInterface.MyFunction(value); 
} 

que je peux appeler comme ceci:

TestFunction<string>(x => return x + " world", "hello"); 

Et le résultat serait « Bonjour tout le monde ».

+1

Vouliez-vous appeler IMyInterface.MyFunction() dans le deuxième bloc de code? – Andy

+0

Oui, merci. Fixé. –

Répondre

2

Puisque les interfaces en C# ne peuvent pas contenir de définitions pour les opérateurs (ou d'autres méthodes statiques d'ailleurs), je crois que la réponse est no. L'alternative est d'utiliser une classe (ne peut malheureusement pas être abstraite, puisque les membres/opérateurs statiques ne valent pas mieux ici que dans les interfaces). Cela vous permettra de définir l'opérateur de conversion implicit et donc d'utiliser le type exactement comme vous l'avez spécifié.

Dans la classe (que vous pourriez peut-être faire virtual si nécessaire), vous devez le définir comme suit.

public class MyClass<T> 
{ 
    public static implicit operator MyClass<T>(Func<T, T> func) 
    { 
     return new MyClass<T>() { MyFunction = func }; 
    } 

    public MyClass() 
    { 
    } 

    public Func<T, T> MyFunction 
    { 
     get; 
     set; 
    } 
} 

Votre définition TestFunction dans votre question devrait alors travailler exactement comme vous il avons écrit.

public T TestFunction<T>(IMyInterface myInterface, T value) 
{ 
    return myInterface.MyFunction(value); 
} 

Et aussi l'appel à TestFunction:

TestFunction<string>(x => return x + " world", "hello"); 

Cela peut ne pas être exactement ce que vous cherchez, mais il est tout de même assez proche, et d'ailleurs très probablement le meilleur que vous serez en mesure obtenir.

+0

Comment TestFunction convertit un lambda en IMyInterface? Vous définissez une classe MyClass, pas une interface. Quelques modifications supplémentaires sont nécessaires, je pense ... –

+0

@Earwicker: Regardez de plus près - l'opérateur de conversion implicite devrait le faire pour vous, à moins que je ne me trompe. Aussi, si vous lisez le début de mon article, je mentionne que ce n'est pas possible avec une interface, et seulement une classe (non-abstraite). – Noldorin

+0

C'est à peu près ce à quoi je m'attendais, mais j'ai déjà su ignorer les choses auparavant et j'espérais que ce serait le cas cette fois-ci. Malheureusement, ce n'est pas le cas. En fait, j'avais déjà ma propre implémentation concrète qui est étrangement similaire à ce que vous avez posté. –

Questions connexes