1

ジェネリックとその適切な宣言/使用に関してまだ無知なまま、問題に近づいています。私は前提を理解していますが、ジェネリックのインアンドアウトのいくつかはまだ私を逃しています。

次のコードが与えられた場合 (はコンパイルされず、 code-smell が含まれます):

public interface IUIConcern<out T> where T : IUIConcernExtension
{

    string Name { get; }
    Func<T> Extend();
}

public class UIConcern
{
    public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
    {
        Concerns.Add(uiConcern);
    }

    public static List<IUIConcern<T>> Concerns{
        get {
            // Logic... 
        }
        set {
            // Logic... 
        }
    }
}

... いくつかの質問を聞きたいんです:

  • 宣言でpublic static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension すでに制約しているのに、なぜこの部分を制約で指定する必要があるのですかTpublic interface IUIConcern<out T> where T : IUIConcernExtension
  • から派生することを知る以外List<>に、自分のを保持するプロパティをどのように持つことができますか?IUIConcern<T>TIUIConcernExtension

繰り返しますが、これはコンパイルされず、正しくないことに気付きました。多くの異なるタイプのIUIConcern<>要素を持つ可能性のある一般的なアイテムのリストを保持する方法を確認するだけです。

ありがとうございました!

4

2 に答える 2

2

問題はインターフェイスにあるわけではありませんが、静的メソッドとプロパティを使用した一般的な実装が原因です。

を定義する必要があると言ったときのGuvanteからの答えは正しかったですがIUIConcernExtension、それはもちろん非常に論理的であるため、直面している問題には関係ないため、その部分を省略したと仮定しています。

コードの問題は、静的メソッドとプロシージャを持つクラスを作成したことです。一般的な定義はクラス レベルではなく、メソッド レベルにあります。このため、プロパティがあり、メソッドが常に同型で!!

call を呼び出すとしましょう:

Register<string>("something", UIConcern<string>) 

しかし、その前にあなたはすでに呼び出しています:

Register<Type>("something", UIConcern<Type>) 

コンパイラはどのようにしてそれを許可するのでしょうか?! したがって、答えは、クラス レベルでジェネリック型を定義することです。これにより、すべてのプロパティとメソッドが同じになります。

また、リストにプライベートメンバーを使用する必要があります。すべてを静的に行うため、正しいコードは次のようになります。

interface IUIConcernExtension
{
    string Name { get; }
}

public interface IUIConcern<out T> where T : IUIConcernExtension
{
    Func<T> Extend();
}

public class UIConcern<T> where T : IUIConcernExtension
{
    private static List<IUIConcern<T>> _Concerns = new List<IUIConcern<T>>();

    public static void Register(string concernName, IUIConcern<T> uiConcern) 
    {
        Concerns.Add(uiConcern);
    }

    public static List<IUIConcern<T>> Concerns
    {
        get { return _Concerns; }
        set { _Concerns = value; }
    }
}
于 2013-05-15T19:49:15.947 に答える
2

たとえば、次のような基本インターフェースが必要です。

public interface IUIConcern
{
    string Name { get; }
}

public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension
{
    Func<T> Extern();
}

どのように定義ConcernsRegister、どのように扱うかによって異なりますT。または、知っているインスタンスのみを処理する場合はT、 a を使用しDictionary<Type, List<IUIConcern>>て何かを保持するか、基本インターフェイスを削除してobject、コントローラー コードで必要なものに応じて using を保存することができます。

于 2013-05-15T18:52:29.677 に答える