Vous ne pouvez pas surcharger une méthode par valeur de retour uniquement (générique ou non). En outre, il serait impossible de résoudre les appels à Bar
, car un objet pourrait implémenter à la fois IAlpha
et IBeta
, ce qui n'est pas possible en utilisant la surcharge.
public class AlphaBeta : IAlpha, IBeta
{
string x {set;}
string y {set;}
}
// too ambiguous
AlphaBeta parkingLot = myFoo.Bar<AlphaBeta>();
Le ci-dessous ne fonctionne pas non plus, parce que les méthodes ne diffèrent que par le type de retour
class Gar
{
public string Foo()
{
return "";
}
public int Foo()
{
return 0;
}
}
Malheureusement, la meilleure solution sera d'utiliser une solution moins générique. Le modèle de commande pourrait vous servir bien ici.
public class Foo
{
private readonly static Dictionary<Type, Command> factories =
new Dictionary<Type, Command>();
static Foo()
{
factories.Add(typeof(IAlpha), new AlphaCreationCommand());
factories.Add(typeof(IBeta), new BetaCreationCommand());
}
public T Bar<T>()
{
if (factories.ContainsKey(typeof(T)))
{
return (T) factories[typeof(T)].Execute();
}
throw new TypeNotSupportedException(typeof(T));
}
}
// use it like this
IAlpha alphaInstance = myFoo.Bar<IAlpha>();
IBeta betaInstance = myFoo.Bar<IBeta>();
Une autre façon de mettre en œuvre Bar qui vous permet d'appeler sans déclarer explicitement le type (dans vos supports coudés) est d'utiliser un paramètre out. Je l'éviterais, cependant, puisque les paramètres de 100% contrôlés sont habituellement mauvais.
public void Bar<T>(out T returnValue)
{
if (factories.ContainsKey(typeof(T)))
{
returnValue = (T) factories[typeof(T)].Execute();
return;
}
throw new TypeNotSupportedException(typeof(T));
}
// call it like this
// T is inferred from the parameter type
IAlpha alphaInstance;
IBeta betaInstance;
myFoo.Bar(out alphaInstance);
myFoo.Bar(out betaInstance);
J'exclus Command
, AlphaCreationCommand
, BetaCreationCommand
et TypeNotSupportedException
. Leur mise en œuvre devrait être assez explicite.
Alternativement, vous pouvez utiliser Func au lieu des commandes, mais cela vous oblige à implémenter tout votre code d'instanciation dans Foo
qui peut devenir incontrôlable au fur et à mesure que votre base de code se développe.
Il ne compilera pas spécifiquement pour les types qui implémentent les deux. Il * compilera * pour tous les autres types cependant (votre mot implique qu'il ne compilera pas, période, à cause de cela). –
Je ne suis pas au courant de quand la surcharge de méthode par le type de retour compilera seulement. Si vous pouvez donner un exemple, je peux modifier ma réponse pour la corriger. –