2017-02-06 5 views
10

Supposons que je l'ai défini deux types indépendants et deux méthodes d'extension avec la même signature mais différents filtres de type:C# résolution méthode générique échoue avec une erreur d'appel ambigu

public class Foo {} 
public class Bar {} 

public static class FooExtensions 
{ 
    public static TFoo Frob<TFoo>(this TFoo foo) where TFoo : Foo { } 
    public static TFoo Brob<TFoo>(this TFoo foo) where TFoo : Foo { } 
} 

public static class BarExtensions 
{ 
    public static TBar Frob<TBar>(this TBar bar) where TBar : Bar { } 
} 

Puis, quand j'écris new Foo().Frob(); je reçois une erreur

error CS0121: The call is ambiguous between the following methods or properties: 'FooExtensions.Frob<TFoo>(TFoo)' and 'BarExtensions.Frob<TBar>(TBar)'

quelqu'un pourrait-il expliquer pourquoi cela ne fonctionne pas et comment l'éviter?

EDIT: Cela se produit dans VS2015 Update 3 et VS2017 RC.

EDIT2: L'idée ici est d'avoir API couramment qui fonctionne sur une hiérarchie de classes:

new Foo() 
    .Frob() 
    .Brob() 
+0

La réponse acceptée est correcte; Je remarque que ce que vous faites ici est une mauvaise pratique. S'il vous plaît ne faites pas de méthodes d'extension qui étendent * tout *, soit en étendant l'objet, ou en étendant le type générique T. Il y a presque toujours un meilleur design. Dans ce cas, pourquoi ne pas simplement étendre Foo et Bar? Quel avantage convaincant est là pour faire ces génériques? –

+0

@EricLippert, j'ai beaucoup simplifié le scénario. En réalité, les méthodes d'extension retournent 'TFoo'. L'idée ici est d'avoir des méthodes API fluides qui fonctionnent sur une hiérarchie de classe. Donc, je pourrais écrire 'new Foo() .Frob() .grob() .Blob();'. Le problème se pose lorsque j'ai deux types indépendants, mais avec des méthodes d'extension prenant des arguments similaires dans le même ordre. –

Répondre

11

La contrainte d'un paramètre de type générique ne fait pas partie de la signature de la méthode. Ces deux méthodes sont essentiellement les mêmes du point de vue de la résolution; Lorsque le compilateur essaie de résoudre l'appel, il voit deux méthodes valides et il n'a aucun moyen de choisir le meilleur, donc l'appel est marqué comme ambigu.

Vous pouvez en savoir plus sur ce numéro here.

+0

Merci pour le lien; Je n'aurais pas dit mieux moi même. –

+3

@EricLippert Un grand merci à vous, il est difficile d'exagérer ce que j'ai appris sur la langue, et la programmation en général, en lisant votre blog. – InBetween