Require a “static” field in a derived class

I have a class hierarchy representing a JSON based API. There is a common factory that calls and deserializes api in classes using .NET 4 (without third-party libraries). I am trying to avoid creating an instance of a class to retrieve read-only information that is unique to each class.

I thought (until I started reading this and this , ...) I would associate a static URL with a base class / interface and then set it in the constructor of the derived class. Something like (this example will not work):

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

This does not work. A static field cannot be abstract and cannot be uniquely set to b and c, since the static variable is stored in the class in which it is defined (url in this case).

How can I use the read-only element associated with the class so that you can access the element (etc.) without having to instantiate the class?

+6
source share
3 answers

I implemented such a template to remind me of the constants that I need to configure for each derived class that should be statically accessible:

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

I even found that after implementing this pattern, polymorphic using a constant is just as useful.

+6
source

I understand that you do not want to request an instance, but keep the method static. This is not possible, the static field is loaded once in the module and cannot be inherited.
I think the only way is to store the dictionary in a helper class, with the type as the key. Like this

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

Or you can decorate the desired types with a custom attribute and save the data in this attribute. Like this

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

Of course, you can pass them all by reflecting and initializing the dictionary, see this question .

+1
source

You can do it like this without a static field. Because the static field belongs to the type!

 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"; } } } 
-1
source

All Articles