我有一个表示基于JSON的API的类层次结构。有一个通用工厂使用.NET 4(没有第三方库)将api调用和反序列化为类。我试图避免必须实例化该类来检索每个类唯一的只读信息。
我曾经想过(直到我开始阅读this和this,...)我会将静态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);
这不起作用。静态字段不是抽象的,也不能在b 和 c中唯一设置,因为静态变量存储在它定义的类中(在本例中为url)。
如何让一个与类关联的只读项目,以便您可以访问该项目(等)而无需实例化该类?
答案 0 :(得分:7)
我已经实现了这样的模式,以帮助提醒我需要为每个派生类设置需要静态访问的常量:
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; }
}
}
我甚至发现在实现这种模式之后,对常量的多态使用同样有帮助。
答案 1 :(得分: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。
答案 2 :(得分:-1)
你可以这样做,没有静态字段。因为静态字段属于某种类型!
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"; }
}
}