![](/img/trans.png)
[英]How to force derived class to implement a static property or field?
[英]Require a “static” field in a derived class
我有一個表示基於 JSON 的 API 的類層次結構。 有一個通用工廠,可以使用 .NET 4(沒有 3rd 方庫)調用 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);
這不起作用。 靜態字段不能是抽象的,也不能在 b和c 中唯一設置,因為靜態變量存儲在它定義的類中(在這種情況下為 url)。
我如何才能擁有與類關聯的只讀項目,以便您可以訪問該項目(等)而無需實例化該類?
我已經實現了一個這樣的模式來幫助提醒我需要為每個派生類設置的常量,這些常量需要靜態訪問:
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; }
}
}
我什至發現在實現這個模式之后,常量的多態使用同樣有用。
我知道您不想詢問實例但要保持方法靜態。 這是不可能的,靜態字段在模塊中加載一次,不能被繼承。
我認為唯一的方法是將字典存儲在助手類中,以類型為鍵。 像這樣
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>();
}
}
當然,您可以通過反射將它們全部傳遞並初始化字典,請參閱此問題。
你可以這樣做,沒有靜態字段。 因為靜態字段屬於一種類型!
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"; }
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.