如何重构重载方法

时间:2010-02-24 07:55:12

标签: c# .net refactoring overloading

我有方法:

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

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

//...

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

decimal,string,[Class1,...,ClassN]中的DateTime
和一种常用的方法:

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

如何创建可扩展系统的任何其他想法,添加新类只需要添加一个方法? (在一个地方添加代码)

3 个答案:

答案 0 :(得分:4)

听起来你需要使用通用方法:

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

这里的好处是你也可以这样限制T:

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

在第二种情况下,您可以将T视为实际的MyClassBase,但您可以自由传递任何对象,只要它是(或派生自){ {1}}。这也适用于接口。

你可以这样称呼这个方法:

MyClassBase

编译器足够聪明,可以知道它是哪种类型,因此您不必将其传递给T类型,但有时您需要在调用方法时显式声明它,如下所示:

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

答案 1 :(得分:1)

我相信你要做的事情被称为多次发送(有人请纠正我,如果我错了),这在.Net框架的当前版本中是不可用的。然而,它是通过动态关键字 - &gt;在.Net 4.0中引入的。 http://blogs.msdn.com/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx

答案 2 :(得分:0)

您可以使用泛型和属性来描述有关该类的某种元数据 泛型很可能会清理你的if语句

嗯...

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

抱歉,我可能更具描述性。 我希望这会有所帮助。