2010-02-24 48 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

'属性描述符',你在谈论属性?你想用代码做什么?可能有设计问题。 –