6

私が取り組んでいるアプリケーションの一部のコードの一貫性、簡潔さ、および読みやすさを改善する方法を検討しています。開始コードは次のようになります。

context.GetGraphType<Bar>().Subscribe<Fizz>(
     (instance, evt) => evt.Execute((Bar)instance.Instance)
);

上記のようなほぼ同一のコード行がいくつかあります。私はそれを次のように書き直したかった:

typeof(Bar).SubscribeTo<Fizz>(context);

一つには、これにより、すでに非公式な慣習となっているものを公式化する利点を活かすことができます。また、「コンテキストがバーの種類を取得し、fizz をサブスクライブしてから何かを実行する」ではなく、「バーが指定されたコンテキストで fizz イベントをサブスクライブする」のようなものになることを期待しました。流れが良くなったと思いますし、聞いた同僚も同意してくれました。

これを拡張メソッドとして実装し始めました。上記を達成するために、イベント型の抽象ジェネリック基本クラスを利用したかったのでFizzEvent<T>. これは、拡張メソッドへのジェネリック型引数が、拡張メソッドが呼び出される型になるように制約する必要があることを意味します。したがって、上記の例でFizzは、 は type である必要がありEvent<Bar>ます。

これは可能ですか?それまでの間、別の解決策を採用しましたが、それが達成できるかどうかはまだ興味があります. 他の提案も大歓迎です。

ありがとう!

編集#1:明確にするために、追加の型パラメーターを使用できることを認識していますが、可能であればそれを回避する方法を探しています。

編集#2:私のシナリオと100%一致しないため、受け入れられた回答をわずかに変更すると思います。要するに、目的を達成するために、Type の拡張メソッドの代わりに汎用静的クラスを使用できるということです。ありがとうdss539!

コードを更新します (オンザフライで行っているため、タイプミスがある可能性があります):

public class Bar { }

public class Event<TSubscriber>
{
    public abstract void Execute(TSubscriber source);
}

public class Fizz : Event<Bar>
{
    public override void Execute(Bar bar)
    {
        // respond to event
    }
}

public class Context { }

public static class ForType<TSubscriber>
{
    public static void SubscribeTo<TEvent>(Context context)
        where TEvent : Event<TSubscriber>
    {
        context.GetType<TSubscriber>().Subscribe<TEvent>(
            (evt, args) => evt.Execute((TSubscriber)args.Source));
    }
}

public static void Run()
{
    ForType<Bar>.SubscribeTo<Fizz>(context);
}
4

3 に答える 3

7

これはあなたが尋ねたとおりではありませんが、おそらくそれで十分でしょう。

internal class Program
{
    static void Main(string[] args)
    {
        var fizzHandler = new Fizz();
        var context = new Context();
        Handle<Bar>.With(fizzHandler, context);
    }
}
public class Bar { }
public class Event<T> { }
public class Fizz : Event<Bar> { }
public class Context { };
public static class Handle<T>
{
    public static void With(Event<T> e, Context c)
    {
        //do your stuff
    }
}
于 2010-07-01T15:59:14.027 に答える
4

一般的な制約を使用してルールを適用できる、もう少し奇抜なことをしてみませんか。

 public static class SubscriptionManager
 {
     public static void SubsribeTo<TSub,TEvent>( Context context )
         where TEvent : Event<TSub>
     {
        /// you code...
     }
 }

呼び出しは次のようになります。

 SubscriptionManager.SubsribeTo<Bar,Fizz>( context );

この制約where TEvent : Event<TSub>により、希望するイベントとサブスクリプション タイプの間の関係が保証されます。私の本では、クラスの拡張メソッドよりも好ましいですType-それはインテリセンスを混乱させる傾向があるためです。Typeは多くの状況で使用され、 のすべてのインスタンスで Intellisense に偽のメソッドが表示さTypeれると混乱する傾向があります。また、ライブラリの消費者にとって、これが「サブスクライブ」する方法であることは明らかではありません-実際にそのコード例を見たことがない限り.

于 2010-06-25T14:54:49.763 に答える
0

おそらく、.NET 型を内部型表現 ( によって返されるものと同じ) に変換するコンテキストに (拡張) メソッドを追加System.Typeして ( を持つように) 拡張することができます。typeof(T).GetGraphType

static class Ext {

    public static TypeofTypeofBar GetGraphTypeFromDotNetType(this Context ctx, Type t) {
       return __something(t);
    }

    public static void SubscribeTo<F, E>(this Type type, Context ctx, E e)
        where E: Event<T> {
        context.GetGraphTypeFromDotNetType(type).Subscribe<F>(a);
    }

}

...

typeof(Bar).SubscribeTo(context, action);
于 2010-06-25T14:56:26.330 に答える