2010-02-24 8 views
3

J'ai les méthodes:Comment refactoriser méthodes surchargées

public MyReturnType MyMethod(Class1 arg) 
{ 
//implementation 
} 

public MyReturnType MyMethod(Class2 arg) 
{ 
//implementation 
} 

//... 

public MyReturnType MyMethod(ClassN arg) 
{ 
//implementation 
} 

décimal, chaîne, DateTime dans [Class1, ..., ClassN]
et une méthode commune:

public MyReturnType MyMethod(object obj) 
{ 
if(obj == null) 
    throw new ArgumentNullException("obj"); 
if(obj is MyClass1) 
    return MyMethod((Class1)obj); 
if(obj is MyClass2) 
    return MyMethod((Class2)obj); 
//... 
if(obj is MyClassN) 
    return MyMethod((ClassN)obj); 
return MyMethod(obj.ToString()); //MyMethod(string) implemented. 
} 

Comment puis-je refactoriser ce code? Je peux utiliser des attributs et le modèle de composant, quelque chose comme ceci:

public class MyAttribute : Attribute 
{ 
public Type Type { get; set; } 
} 

public MyReturnType MyMethod(object obj) 
{ 
    if(obj == null) 
     throw new ArgumentNullException("obj"); 
var protperty = TypeDescriptor.GetProperties(this, new Attribute[] { new MyAttribute() }) 
    .Cast<PropertyDescriptor>().FirstOrDefault(x => 
    x.GetAttribute<MyAttribute>().Type.IsInstanceOfType(obj)); 
if (protperty != null) 
    return protperty.GetValue(obj) as MyReturnType; 
return MyMethod(obj.ToString()); 
} 

mais cela semble assez difficile à comprendre et peut créer des bugs. Par exemple, si quelqu'un déclare méthode comme

[MyAttribute(Type = ClassNplus1)] 
public NotMyReturnType MyMethod(ClassNplus1 arg); 

D'autres idées comment créer un système extensible, où l'ajout de nouvelles classe est nécessaire que d'ajouter une méthode? (Ajouter du code dans un endroit)

Répondre

1

Je crois que ce que vous essayez de faire est connu comme envoi multiple (quelqu'un s'il vous plaît corrigez-moi si je me trompe) et ce n'est pas disponible dans les versions actuelles du framework .Net. Cependant, il est introduit dans .Net 4.0 via le mot-clé dynamique ->http://blogs.msdn.com/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx.

+0

Oui, cela ressemble à ce que je recherche, mais je peux utiliser le framework 3.5. Est-il possible de le simuler? merci pour le lien. – Steck

+0

Je n'ai pas implémenté ce modèle moi-même mais lorsque je parle à des collègues, il est courant d'utiliser le modèle de répartition double. Il est décrit ici -> http://www.garyshort.org/blog/archive/2008/02/11/double-dispatch-pattern.aspx. Espérons que cela aide – mattythomas2000

0

Vous pouvez utiliser Generics et attributs pour décrire une sorte de méta-données sur la classe Le Generics sera très probablement nettoyer votre instruction if

Hmmm ...

public class MyClass<T> 
{ 
    public OtherClass ReturnSomething(T checkThisType) 
    { 
    } 
} 

Désolé je pourrais être plus descriptif. J'espère que cela aide.

4

On dirait que vous avez besoin d'utiliser des méthodes génériques:

public MyReturnType MyMethod<T>(T arg) 
{ 
    // implementation 
} 

La bonne chose est que vous pouvez également restreindre T comme ceci:

public MyReturnType MyMethod<T>(T arg) where T : MyClassBase 
{ 
    // implementation 
} 

Dans le second cas, vous pouvez traiter T comme s'il s'agissait d'un réel MyClassBase, mais vous êtes libre de passer dans n'importe quel objet, tant qu'il est (ou dérive de) MyClassBase. Cela fonctionne également pour les interfaces.

Vous appelez cette méthode comme ceci:

MyMethod(new MyClass1()); 
MyMethod(new MyClass2()); 
MyMethod(new MyClass3()); 

Le compilateur est assez intelligent pour savoir quel type il est donc vous ne devez pas passer le type de T, mais parfois vous devez déclarer explicitement lors de l'appel de la méthode, comme ceci:

MyMethod<MyClass1>(new MyClass1()); 
MyMethod<MyClass2>(new MyClass2()); 
MyMethod<MyClass3>(new MyClass3()); 
+0

Mon code aussi appelé à partir des descripteurs de propriété, donc MyMethod (objet) ou un gestionnaire pour résoudre le type correct est requis. Cette question peut être réduite à la question de l'écriture du gestionnaire. – Steck

+0

Par «descripteurs de propriétés», parlez-vous des attributs? Qu'essayez-vous de faire avec le code? Il peut y avoir un problème de conception. –