3

いくつかの異なるオブジェクトがありますが、それらに対して同様のアクションを実行する必要があります。1. いくつかのメソッドを使用し、これらのオブジェクトを型パラメーターとして使用します。2. System.Object をパラメーターとして取得する 1 つのメソッドを使用します。そして、このメソッド内で、パラメーターのタイプをチェックし、何らかのアクションを実行します。

たとえば、いくつかのアクションについて通知を送信する必要があります。これらのアクションの詳細を含むオブジェクト 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

最初のものはタイプ セーフですが、2 番目のものはそうではありません。したがって、これら 2 つのオプションのどちらかを選択する必要がある場合は、最初のオプションを選択します。

一方で、まったく別のアプローチで行くことはできないのでしょうか? 1 つの基本クラスまたはインターフェイス 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 に答える
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 に答える
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();
    }
}

Factoryは正しい実装を提供でき、既存のインターフェースを壊すことなくさらに実装を提供できます...

于 2012-04-11T11:45:20.100 に答える
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

みんなが言ったように、それは状況によって異なりますが、一般的に私は2番目のアプローチのバリエーション(以下)を好みます。将来的に拡張する方が簡単だからです(もちろん、必要に応じて)。

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

オブザーバー パターンの使用を検討しましたか

ウィキリンクはこちら。

手短に言えば、新聞を購読しているとしましょう。新聞の新しい版 (イベント) があるときはいつでも、購読者は通知を受け、新しいバージョンが配信されます。

于 2012-04-11T12:33:33.320 に答える
0

私は最初のアプローチで行きます。

より多くのメソッドを作成する必要があり、場合によってはもう少し多くのコードを作成する必要がありますが、私はそれがはるかに使いやすく、型安全であると信じています.

あなたの2番目のアプローチでは、コードを読まずにメソッドが期待しているオブジェクトの種類をコンパイル時に知ることができません(ライブラリとして使用するためにこのコードを配布すると想像してください)。あなたができることは、実行時に失敗させることです-素晴らしいことではありません。

于 2012-04-11T11:38:06.313 に答える