3

我有几个不同的对象,但我必须对它们执行类似的操作。使用什么比较好: 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
   }
4

8 回答 8

8

我想这取决于:

发送通知的代码大致相同吗?那我会选择:

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

否则我可能会选择重载该方法:

public void SendNotification(Action1 action) {}
public void SendNotification(Action2 action) {}
public void SendNotification(ActionN action) {}
于 2012-04-11T11:39:28.947 回答
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();
   ...
}
于 2012-04-11T11:37:40.827 回答
2

策略模式也可能适合这里:

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();
    }
}

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

于 2012-04-11T11:45:20.100 回答
0

我会采用第一种方法。

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

您的第二种方法不允许我在编译时知道该方法期望什么样的 Object 而无需阅读代码(想象您分发此代码以用作库),如果我通过了错误的方法,唯一的事情你可以做的是让它在运行时失败 - 不是很好。

于 2012-04-11T11:38:06.313 回答
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);
        }
} 
于 2012-04-11T11:47:01.913 回答
0

这是我的尝试:

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

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

如果某些通知具有通用实现,则将其放在 Action 类中。

现在在发送通知的班级中这样做:

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

}

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

于 2012-04-11T17:29:46.447 回答
0

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

SendNotification方法可以这样构建:

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

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

[abstract class] [interface] SpecialAction {
    public string GetName();
    public bool CanDoX();
}
于 2012-04-11T11:43:37.840 回答
0

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

维基链接在这里。

简而言之,假设您订阅了一份报纸,当有新版本的报纸(事件)时,订阅者将收到通知并交付新版本。

于 2012-04-11T12:33:33.320 回答