我有方法:
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);
如何创建可扩展系统的任何其他想法,添加新类只需要添加一个方法? (在一个地方添加代码)
答案 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)
{
}
}
抱歉,我可能更具描述性。 我希望这会有所帮助。