How to bind a static string to a C # object type

I have a method that requests a rest API where I do a mapping from JSON to an object. Since the query string and the type of object that I pass to this method should always match, I would like to include the query string as a static string.

public class Root { public static string Query; } public class RootObject : Root, IRootObject { public D d { get; set; } public static new string Query = "AccountSet"; } public interface IRootObject { D d { get; } } public class RestClass { public void Connect<T>() where T : Root, IRootObject { T.Query <-- fails (not actual code. Just to show my problem) } } 
+5
source share
2 answers

To do this, you can use the special attribute:

 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class QueryAttribute : Attribute { public string QueryString { get; private set; } public QueryAttribute(string queryString) { QueryString = queryString; } public static string GetQueryStringForType(Type type) { var queryAttr = type.GetCustomAttributes(typeof(QueryAttribute), false) .FirstOrDefault() as QueryAttribute; return queryAttr != null ? queryAttr.QueryString : null; } } 

Use it for your classes:

 [Query("AccountSet")] public class RootObject : Root, IRootObject { public D d { get; set; } } 

And get a value like this:

 public void Connect<T>() where T : Root, IRootObject { var query = QueryAttribute.GetQueryStringForType(typeof(T)); } 
+4
source

Unlike languages ​​like Delphi , C #, and the .NET CLI, they don’t support the concept of static polymorphism at all.

Therefore, you will need another way to bind type information to your types, two of which I propose here:

  • You can use a custom attribute to mark your class. This attribute can be obtained from typeof(T) using reflection methods such as GetCustomAttributes . Once you have defined your attribute class, these attributes are fairly easy to declare for each type that you want to pass in T The disadvantage is that there is no way to check compilation time if every class passed to T is decorated with such an attribute.
  • Alternatively, you can go to the "information object". Create a base class ObjectInfo<T> , which serves as a factory for an instance of type T and as a repository for some meta information on T , for example, your Query string. For each type you want to pass to T , subclass your ObjectInfo<T> where T : Root class (for example, create the RootObjectInfo : ObjectInfo<RootObject> , which overrides the Query ObjectInfo<T> property to return the corresponding row). Then change Connect<T> , so ObjectInfo<T> is required as an argument.
+1
source

Source: https://habr.com/ru/post/1214731/


All Articles