2010-02-24 45 views
3

我的方法:如何重構重載方法

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

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

//... 

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

十進制數,字符串,日期時間在[1類,...,ClassN]
和一個常用的方法:

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. 
} 

如何我可以重構這段代碼嗎?我可以使用屬性和組件模型,像這樣:

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()); 
} 

但它看起來很難理解,並且可能會產生一些錯誤。例如,如果有人宣稱像

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

任何其他的想法如何創建可擴展的系統,在增加新的類只需要添加一個方法的方法? (在一個地方添加代碼)

回答

1

我相信你正在嘗試做的是被稱爲多分派(有人請糾正我,如果我錯了),這是不是在.NET Framework的當前版本。但是它正在通過動態關鍵字 - >http://blogs.msdn.com/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx在.Net 4.0中引入。

+0

是的,這看起來像我在找什麼,但我可以使用3.5框架。有沒有可能模擬它? 感謝您的鏈接。 – Steck

+0

我自己並沒有實現這個模式,但是當與同事聊天時,常常會使用雙重調度模式。這裏描述 - > http://www.garyshort.org/blog/archive/2008/02/11/double-dispatch-pattern.aspx。希望這有助於 – mattythomas2000

0

你可以使用泛型和屬性來描述某種元數據的關於類 仿製藥將最有可能清理你的if語句

嗯...

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

對不起,我可能是更多的描述。 我希望這可以幫助。

4

聽起來像是你需要使用泛型方法:

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

這裏的好處是,你還可以限制t等這樣:

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

在第二種情況下,你可以把T因爲如果它是一個實際的MyClassBase,但你可以自由在任何物體通過,只要它是(或派生)MyClassBase。這也適用於接口。

你這樣調用方法,以便:

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

編譯器是足夠聰明,知道哪種類型是這樣,你不必把它傳遞T的類型,但有時你需要顯式聲明它調用方法時,像這樣:

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

我的代碼也從屬性描述符中調用,所以MyMethod(對象)或某些管理器需要解析正確的類型。 這個問題可以簡化爲編寫經理的問題。 – Steck

+0

'屬性描述符',你在談論屬性?你想用代碼做什麼?可能有設計問題。 –