9

JSON ベースの API を表すクラス階層があります。.NET 4 (サードパーティのライブラリなし) を使用して、API を呼び出してクラスに逆シリアル化する汎用ファクトリがあります。クラスをインスタンス化して、各クラスに固有の読み取り専用の情報を取得する必要がないようにしています。

私は (これこれを読み始めるまでは...) 静的 URL を基本クラス/インターフェースに関連付け、それを派生クラスのコンストラクターに設定すると思っていました。次のようなもの (この例は機能しません):

abstract class url {
  public abstract static string URL; // This is invalid syntax!
}

class b : url {
  static b () { URL = "http://www.example.com/api/x/?y=1"; }
}

class c: url {
  static c () { URL = "http://www.example.com/api/z"; }
}

// ... so the factory can do something like ...
b result = doJSONRequest<b>(b.URL);

これはうまくいきません。static フィールドは抽象化できません。また、静的変数は定義されているクラス (この場合は url) に格納されるため、 bとc で一意に設定することもできません。

クラスをインスタンス化せずに項目 (など) にアクセスできるように、読み取り専用の項目をクラスに関連付けるにはどうすればよいですか?

4

3 に答える 3

9

静的にアクセスできる必要がある派生クラスごとに設定する必要がある定数を思い出させるために、次のようなパターンを実装しました。

public abstract class Foo
{
    public abstract string Bar { get; }
}

public class Derived : Foo
{
    public const string Constant = "value";
    public override string Bar
    {
        get { return Derived.Constant; }
    }
}

このパターンを実装した後、定数のポリモーフィックな使用が同様に役立つことがわかりました。

于 2012-12-18T17:58:19.210 に答える
1

インスタンスに問い合わせる必要はなく、メソッドを静的に保つ必要があることは理解しています。これは不可能です。静的フィールドはモジュールに一度ロードされ、継承できません。
唯一の方法は、型をキーとして辞書をヘルパー クラスに格納することだと思います。このような

class Helper
{
    static Dictionary<Type,string> _urls;
    public static string GetUrl(Type ofType)
    {
        return _urls[ofType];
    }

    public static void AddUrl(Type ofType, string url)
    {
        _urls.Add(ofType,url);
    }
}
class b
{
    static b(){ Helper.AddUrl(typeof(b),"  ");}
}
class Program
{
    b result= doJSONRequest<b>(Helper.GetUrl(typeof(b));
}

または、目的の型をカスタム属性で装飾し、その属性にデータを格納することもできます。このような

class UrlAttribute:Attribute
{
    public string Url{get;private set;}
    public UrlAttribute(string url){Url=url;}
}
[Url("someurl")]
class b { }
class Program
{
    void Main()
    {
        UrlAttribute attr = (UrlAttribute)Attribute.GetCustomAttribute(typeof(b), typeof(UrlAttribute));
        //in dot net 4.5 you can ask the type itself
        UrlAttribute attr = (UrlAttribute)typeof(b).GetCustomAttribute(typeof(UrlAttribute));
        //now you can write that...
        b result = doJSONRequest<b>(attr.Url);
    }
    //or even you can do that in doJSONRequest itself
    public T doJSONRequest<T>()
    {
         UrlAttribute attr = (UrlAttribute)typeof(T).GetCustomAttribute(typeof(UrlAttribute));
        ...
        //call it: b result=doJSONRequest<b>();
    } 
}

もちろん、それらすべてをリフレクションによって渡し、辞書を初期化できます。この質問を参照してください。

于 2012-12-18T18:12:00.347 に答える
-2

静的フィールドなしで、このように行うことができます。静的フィールドはタイプに属しているためです!

abstract class url
{
    public virtual string URL { get; } // This is invalid syntax!
}

class b : url
{
    public override string URL
    {
        get { return "http://www.example.com/api/x/?y=1"; }
    }
}

class c : url
{
    public override string URL
    {
        get { return "http://www.example.com/api/z"; }
    }

}
于 2012-12-18T18:02:51.913 に答える