如何重构方法的重载

3
我有以下方法:

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

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

//...

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

[Class1, ... , ClassN]中的decimal、string和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个回答

4
听起来你需要使用通用方法:
public MyReturnType MyMethod<T>(T arg)
{
    // implementation
}

这里的好处是您还可以这样限制 T:
public MyReturnType MyMethod<T>(T arg) where T : MyClassBase
{
    // implementation
}

在第二种情况下,您可以像处理实际的一样处理T>,但是只要它是(或派生自),您就可以自由地传递任何对象。这也适用于接口。
您可以这样调用此方法:
MyMethod(new MyClass1());
MyMethod(new MyClass2());
MyMethod(new MyClass3());

编译器足够聪明,知道它是哪种类型,因此您不必传递T的类型,但有时在调用方法时需要显式声明它,如下所示:
MyMethod<MyClass1>(new MyClass1());
MyMethod<MyClass2>(new MyClass2());
MyMethod<MyClass3>(new MyClass3());

我的代码还可以从属性描述符中调用,因此需要MyMethod(object)或某个管理器来解析正确的类型。 这个问题可以简化为编写管理器的问题。 - Steck
“通过‘属性描述符’,你是指属性吗?你想用代码做什么?可能存在设计问题。” - Daniel T.

1

是的,这看起来像是我正在寻找的东西,但我可以使用3.5框架。是否有可能模拟它? 感谢提供链接。 - Steck
我自己没有实现过这个模式,但是在和同事交流时,常见的解决方法是使用双重分派模式。这里有详细描述 -> 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)
   {
   }
}

很抱歉我无法更详细地说明。 希望这可以帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接