如果(obj是thisObj)语句太多了

Jam*_*art 13 c#

我目前有方法试图找出收到的obj是什么.它知道是在某个接口上,例如IService,但是我有代码查看它并试图告诉我它是例如Service1还是Service2.我目前有很多if(obj是thisObj)样式语句,什么是使这段代码漂亮的最佳解决方案?

这是我的确切样本:

    public void DoSomething(IService service)
    {
        if (service is Service1)
        {
            //DO something
        }

        if (service is Service2)
        {
            //DO something else
        }           
    }
Run Code Online (Sandbox Code Playgroud)

现在有两个不是太糟糕的事情,但我看到可能有20多个这些使用起来很糟糕.

有任何想法吗?


确定需要进一步的细节,这里是:

在这个方法之前,我有另一种方法,即接收一个xml doc,它将它们反序列化到接口IService中,所以我们有这样的东西:

    private static void Method(InnerXml)

    {

            var messageObj = (IServiceTask)XmlSerialization.Deserialize(typeof(IServiceTask), InnerXml);

            var service = GetService(messageObj);
            service.PerformTask(xmlDoc);

    }

    private static IService GetService(IServiceTask messageObj)
    {
        var service = new IService ();

        if (messageObj is Task1)
        {
            service = (SomeService)messageObj;
        }

        if (messageObj is Task2)
        {
            service = (SomeOtherService)messageObj;
        }
        return service ;
    }
Run Code Online (Sandbox Code Playgroud)

希望这会让它更清晰一些.

Ita*_*aro 17

你能改变IService吗?

添加方法DoSomething()并在所有服务中实现它.


Jon*_*eet 13

嗯,这取决于//DO something线路在做什么.在某些情况下,在服务接口中声明一个方法并将这些操作的逻辑放在服务本身中是合适的.

有时,在另一方面,它的代码服务本身不应该知道的-在这一点的生活变得明显丑陋:(有时候这种类型的.事情真的是难以避免的,我偶然发现,仿制药的混合物, lambda表达式有帮助,例如

ConditionallyExecute<Service1>(service, s1 => s1.CallSomeService1Method());
ConditionallyExecute<Service2>(service, s2 => s2.CallSomeService2Method());
...
Run Code Online (Sandbox Code Playgroud)

在哪里ConditionallyExecute是这样的:

private void ConditionallyExecute<T>(object obj, Action<T> action)
    where T : class
{
    T t = obj as T;
    if (t != null)
    {
       action(t);
    }
}
Run Code Online (Sandbox Code Playgroud)

......但是当我这样做时,我并不高兴 :(


小智 9

我喜欢在这些场景中使用字典.

Dictionary<Type,Action<IService>>
Run Code Online (Sandbox Code Playgroud)


Mic*_*mlk 4

我相信你想要的是:

class ServiceFactory 
{
     Dictionary<Type, NewService> serviceCreators;
     ServiceFactory() 
     {
         serviceCreators = new Dictionary<Type, NewService>();
         serviceCreators.Add(typeof(Task1), delegate { return new SomeService(); });
         serviceCreators.Add(typeof(Task2), delegate { return new SomeOtherService(); });
     }

     public IService CreateService(IServiceTask messageObj) 
     {
         if(serviceCreators.Contains(messageObj.GetType()) 
         {
              return serviceCreators[messageObj.GetType()];
         }
         return new DefaultService();
     }
}

delegate IService NewService();
Run Code Online (Sandbox Code Playgroud)

IServiceTask或者也许向-添加一个新方法CreateService