2017-10-27 5 views
1

クラスに新しい関数を追加することによって、関数パラメータ/ジェネリック型に応じて外部クラスの関数をカスタマイズ(自己書き換え)したいと思います。パラメータ/汎用に応じて関数をカスタマイズ/オーバーライド

たとえば、ここではhttp://automapper.readthedocs.io/en/latest/Custom-value-resolvers.html#custom-constructor-methodsと同じですが、カスタムインターフェイスが作成され、オブジェクトに追加されました。

私はタイプT(例えばclass2)のためのインターアートを にして、このインターフェースをclass1に追加したいと思います。class1から関数を呼び出すときには、このインターフェース/関数を使うべきです。

object1(of class1).add(Interface x, typeof(class2)) 
object1(of class1).DoSomething<class2>() -> calls interface/function x 

ここと同じ機能:(ただし、インスタンスの作成ではなく、class1に自身にあることが必要とされた後DoSomethingYが追加されていない機能 - 私が作りたいいけない)

public class class1 { 

    private DoSomething1.. 
    private DoSomething2.. 
    private DoSomethingDefault.. 

    public T DoSomething<T>() 
    { 
    if(typeof(t) == ...) 
     return DoSomething1(); 
    else(typeof(T) == ..) 
     return DoSomething2(); 
    else 
     return DoSometingDefault(); 
    } 
} 

だから私の質問。私は何を使用しますか?インタースペース、代議員?そして、どこに/私はこれを保管していますか?

EDIT:

public interface IDoSomething<T> 
{ 
    public T Work(string obj) 
} 

public DoSomething1 : IDoSomething<class2> 
{ 
    public class2 Work() 
    { 
    return new class2() {name = "xx"} { 
    } 
} 

var obj1 = new class1(); 
obj1.Register<class2>(DoSomething1) // might be wrong syntax, but my intention 
// or obj1.Register(tyopeof(class2),DoSomething1); 

class2 obj2 = obj1.DoSomething<class2>(); 
//obj1/class1 should call DoSomething1.Work(); 

class3 obj3 = obj1.DoSomething<class3>(); // should call default if not registered 

もう少し明確にするためには、これは通常のデザインパターンですか?デフォルトのクラス関数を使用する代わりにカスタム関数を呼び出す?

答えて

1

私はあなたのことを正しく理解しています。次のようなものが必要です:

var _do = new Do(); 

_do.Register<I1>(() => Console.WriteLine("I1 action")); 
_do.Register<I2>(() => Console.WriteLine("I2 action")); 

_do.Work<I1>(); 
_do.Work<I2>(); 
_do.Work<string>(); 

public class Do { 
    IDictionary<Type, Action> actions = new Dictionary<Type, Action>(); 

    private void DefaultAction(){ 
     Console.WriteLine("Default action called"); 
    } 

    public void Register<T>(Action act){ 
     var type = typeof(T); 
     if(!actions.ContainsKey(type)){ 
      actions.Add(type, act); 
     } 
    } 

    public void Work<T>() 
    { 
     var type = typeof(T); 
     if(actions.ContainsKey(type)) 
     { 
      actions[type](); 
     } 
     else 
     { 
      DefaultAction(); 
     } 
    } 
} 

public interface I1 { } 

public interface I2 { } 
+0

ありがとう!これは私が望むもののようなものですが、私は十分具体的ではありません(EDITを参照)。 DoSomethingがInterfaceの関数を呼び出すのを止めてしまいます。これは標準的なデザインパターンだと思います。ではない? – Alexander

+0

TryGetValueを使って 'ContainsKey(type)'、 'actions [type]'の代わりに 'if(TryGetValue(type、out temp)){temp();}'を使用すると、 2つの代わりに辞書内の単一の検索。 –

関連する問題