9

我有一个代表基于 JSON 的 API 的类层次结构。有一个通用工厂,它使用 .NET 4(没有第 3 方库)调用 api 并将其反序列化为类。我试图避免必须实例化类来检索每个类唯一的只读信息。

我曾想过(直到我开始阅读thisthis,...)我会将静态 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);

这行不通。静态字段不能是抽象的,也不能在 bc 中唯一设置,因为静态变量存储在它定义的类中(在本例中为 url)。

我怎样才能有一个与类关联的只读项,这样您就可以访问该项目(等)而无需实例化该类?

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>();
    } 
}

当然,您可以通过反射将它们全部传递并初始化字典,请参阅this question

于 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 回答