public dynamic obj1( dynamic obj2)
{
if (obj2.GetType() == typeof(Obj3)
{
//do something
}
if (obj2.GetType() == typeof(Obj4)
{
//do something else
}
if (obj2.GetType() == typeof(Obj5)
{
//do something else
}
//return something
}
有没有办法可以改善这个?我要比较大约70个不同的物体,我不能用反射......我不知道如何改善它。
这个函数的调用者将传递正确的类型(不是动态的),但它返回一个动态,我不知道从哪一个开始
答案 0 :(得分:4)
您可以使用第一类函数执行某些操作,这绝对是我在javascript中执行此操作的方法。
但是,即使在c#中,功能方法在仪式上更低,更可测试,并且删除了大部分样板。在我看来,面向对象的替代方案在意图方面只是混淆了水域:
以下是lambdas的简化示例:
using System;
using System.Collections.Generic;
class MainClass {
public static void Main (string[] args) {
var contents = new Dictionary<System.Type, Func<dynamic, string>>
{
{typeof(int), o => "is int"},
{typeof(string), o => "is string"}
};
Func<dynamic, string> worker = o => contents[o.GetType()](o);
Console.WriteLine(worker(1));
Console.WriteLine(worker("foo"));
}
}
您可以在此处运行: https://repl.it/CGJO/4
您在字典中为要处理的每种类型添加了一个函数。当然,如果函数很长,那么你就不会使用lambdas,你可以这样声明它们:
Func<dynamic, string> intFunc = delegate(dynamic o)
{ return "Is integer";};
Func<dynamic, string> stringFunc = delegate(dynamic o)
{ return "Is string";};
var contents = new Dictionary<System.Type, Func<dynamic, string>>
{
{typeof(int), intFunc}, {typeof(string), stringFunc}
};
答案 1 :(得分:2)
如果您可以更改各种Obj
,则可以创建界面:
public interface IObjectHandler
{
void Dispatch();
}
显然将签名更改为您需要的签名。
现在将该接口放在所有对象上,并在Dispatch
方法中实现与每个对象相关的代码。
最后但并非最不重要的是你可以这样称呼它:
public dynamic obj1( dynamic obj2)
{
IObjectHandler tmp = obj2 as IObjectHandler;
if(tmp != null)
tmp.Dispatch();
}
现在这并没有真正利用dynamic
这一事实。事实上,你甚至可以在这种情况下改变你的签名:
public IObjectHandler obj1( IObjectHandler obj2)
这显然只适用于您创建的类,但由于您没有提供更多信息,因此这是另一种方法。
如果这需要适用于int
,string
等内容,则根本不起作用。
现在,如果您的对象都在继承层次结构中,那么为您打开不同的选项。您可以在基类中实现该方法,然后根据需要进行覆盖。
答案 2 :(得分:1)
有没有办法可以改善这个?
为每种类型创建一个重载。获胜的代码量;与70种不同的w3
语句有很大不同,并且您具有编译时类型安全性。
您没有说每种类型的代码有多么不同,但希望有一些基类或某些东西可以减少函数的数量。
答案 3 :(得分:0)
如果您不想重载或创建界面,可以使用旧的switch case
或甚至使用else if
语句。