哪种代码编程风格更好

时间:2012-04-11 11:34:06

标签: c# .net polymorphism

我有几个不同的对象,但我必须对它们做类似的操作。 什么是更好用: 1.几种方法并将这些对象用作类型参数。 2.使用一个将System.Object作为参数的方法。在这个方法中,我将检查参数类型并执行一些操作。

例如,我应该发送一些动作的通知。我有对象Action1,Action2,Action3 ... ActionN,其中包含这些操作的详细信息。我应该使用:

   public void SendNotificationForAction1(Action1 action) {}
   public void SendNotificationForAction2(Action2 action) {}
   public void SendNotificationForActionN(ActionN action) {}

   public void SendNotification(Object action) 
   {
       //here I will check type of action and do something
   }

8 个答案:

答案 0 :(得分:8)

第一个是类型安全的,第二个不是。因此,如果我要在这两个选项之间做出选择,我会选择第一个选项。

另一方面,是不是可以采用完全不同的方法? 在哪里有一个基类或接口Action,其他类派生自何处? 接口或基类可以有一个“GetDetailsForNotification”方法,您可以在实现者中实现,并且可以在SendNotificationForAction方法中使用该方法。

这样的事情,但是,当然,我不知道这在你的背景下是否可行:

interface IAction
{
   string GetDetailsForNotification();
}

public class Action : IAction{
   public string GetDetailsForNotification()
   {
        return "details from Action";
   }
}

public class Action2 : IAction{
   public string GetDetailsForNotification()
   {
        return "details from Action2";
   }
}


public void SendNotificationForAction(IAction action) {

   var details = action.GetDetailsForNotification();
   ...
}

答案 1 :(得分:8)

我想这取决于:

发送通知的代码是或多或少相同?然后我会选择:

public void SendNotificationFor<T>(T action) {}

否则我可能会选择overload方法:

public void SendNotification(Action1 action) {}
public void SendNotification(Action2 action) {}
public void SendNotification(ActionN action) {}

答案 2 :(得分:2)

Strategy Pattern也适用于此:

private interface INotificationStrategy<T> // or non-generic with object
{
    void SendNotification(T action);
}

public class StringNotificationStrategy : INotificationStrategy<string>
{
    public void SendNotification(string action)
    {
        throw new NotImplementedException();
    }
}

工厂可以为您提供正确的实现,您可以在不破坏现有接口的情况下提供进一步的实现......

答案 3 :(得分:0)

我会采用第一种方法。

它需要创建更多的方法,可能还需要更多的代码,但我相信它更容易使用和类型安全。

你的第二种方法不允许我在编译时知道方法在没有读取代码的情况下期望什么样的Object(想象一下你将这个代码分发用作库),如果我传递了错误的方法,你唯一能做的就是让它在运行时失败 - 不是很好。

答案 4 :(得分:0)

您应该尽量保持方法的通用性。

可以像这样构建SendNotification方法:

public void SendNotification<T>(T action) where T : SpecialAction {
}

然后,类/接口SpecialAction可以具有不同操作之间的方法。例如:

[abstract class] [interface] SpecialAction {
    public string GetName();
    public bool CanDoX();
}

答案 5 :(得分:0)

正如大家所说,这取决于,但通常我更喜欢第二种方法的变化(下面),因为它在将来更容易扩展(当然,如果你需要的话)。

interface ISendNotificationHandler
{
    Type ActionType { get; }
    void SendNotification(object action)
}  


class Action1SendNotificationHandler : ISendNotificationHandler
{
    public Type ActionType {get{return typeof(Action1);}}
    public void SendNotification(object action)
    {
        Action1 a = (Action1)action;
        // TODO: send notification
    }   
}

// your method originally posted 
public void SendNotification(Object action)     
{
        var handlers = new ISendNotificationHandler[]{ new Action1SendNotificationHandler(), /* etc*/}

        // 
        var handler = handlers.FirstOrDefault(h=>action.GetType().IsSubclassOf(h.ActionType))
        if(handler != null)
        {
            handler.SendNotification(action);
        }
        else
        {
            throw new Exception("Handler not found for action " + action);
        }
} 

答案 6 :(得分:0)

您是否考虑过使用观察者模式

Wiki Link 就在这里。

为了简短起见,假设您订阅了一份新闻报道,当有新版本(活动)的新闻报道时,订阅者将收到通知,并且会发送新版本。

答案 7 :(得分:0)

这是我的尝试:

每个ActionN类都派生自基本Action:

class Action1: Action, INotify
{
   public void override SendNotification() {...}
}

如果某些通知具有共同的实现,则将其置于Action类中。

现在在发送通知的班级中执行以下操作:

class Sender
{
    public void SendNotif(INotify actn)
    {
       actn.SendNotification();
    }

}

并将适当的对象发送到SendNotif()方法。