Is there a clause that I can put along the lines of "where : TypeOf(T1) != TypeOf(T2)"
Vous pourriez faire en sorte que votre constructeur lance une exception lors de l'exécution. Mais il n'y a aucun moyen d'empêcher cette situation à l'heure de compilation.
Any way to make this unambiguous?
Vous devez modifier les noms de vos méthodes afin qu'elles ne se chevauchent pas. C'est de loin la chose la plus sûre et la plus facile à faire. En fait, IIRC le CLR se réserve le droit de ne pas créer un type qui produit une ambiguïté dans les signatures de méthodes comme celle-ci. (Évidemment, notre mise en œuvre réussit réellement, mais vous marchez sur une glace très mince lorsque vous tirez ces sortes de manigances.)
Faire ce genre de chose est vraiment une très mauvaise idée parce que cela peut vous mener dans toutes sortes de situations. difficulté. Voici un exemple de la façon dont les choses vont terriblement mal:
http://blogs.msdn.com/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx
http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx
Notez également que le compilateur va vous empêcher de créer un type tel qu'il implémente deux interfaces qui pourraient être identiques En construction. Cette pratique est illégale:
class C<T, U> : IFoo<T>, IFoo<U> { ... }
parce que vous pouvez ensuite construire C<int, int>
et le CLR n'aurait aucun moyen de savoir quelles méthodes qui correspondent aux emplacements d'interface.
Mais je semble avoir digressé un peu. Retour sur le sujet
Puisque vous êtes le créateur de cette classe, vous pouvez choisir de renommer vos méthodes "Bar" afin qu'elles soient différentes dans n'importe quelle construction possible. Supposons que vous choisissiez obstinément de ne pas le faire. Y at-il quelque chose que l'utilisateur de votre classe malheureuse peut faire si elles veulent faire Widget<int, int>
? Oui, en fait, il y a, comme le souligne kvb. Ils peuvent définir des méthodes d'extension qui font la bonne chose.
public static void BarTheFirst<A, B>(this Widget<A, B> w, A a)
{
w.Bar(a);
}
public static void BarTheFirst<A, B>(this Widget<A, B> w, B b)
{
w.Bar(b);
}
résolution de surcharge se fait au moment de la compilation, et au moment de la compilation tout ce que nous savons est que le premier appelle la barre qui prend un « A », et le second appelle la barre qui prend " B ". Nous ne refaisons pas la résolution de surcharge à l'exécution, alors maintenant vous pouvez dire
Widget<int, int> w = whatever;
w.BarTheFirst(5);
w.BarTheSecond(10);
et il fera le bon choix.
Je me demande quel est le cas du monde réel pour cela ... – user76035
en réalité, il devient et la méthode invalide sur le chargement – Perpetualcoder
@wwosik: Un dictionnaire avec 2 clés. –