I have a method that queries a rest API where I do a mapping from JSON to an object. Since the query string and object type I pass to this method always have to match I wanted 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)
     }  
}
                You could use a custom attribute for this:
[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 on your classes:
[Query("AccountSet")]
public class RootObject : Root, IRootObject
{
    public D d { get; set; }
}
And retrieve the value like this:
public void Connect<T>() where T : Root, IRootObject
{
    var query = QueryAttribute.GetQueryStringForType(typeof(T));
}
                        As opposed to languages such as Delphi, C# and the .NET CLI in general do not support the concept of static polymorphism.
Therefore, you will require some other way to attach the type-specific information to your types, two of which I suggest here:
typeof(T) with reflection methods such as GetCustomAttributes. Once you have defined your attribute class, these attributes are quite easy to declare for each type that you want to pass to T. The downside is that there is no way to compile-time check whether every class passed to T is adorned by such an attribute.ObjectInfo<T> that serves as a factory for an instance of type T and as a storage for some metainformation on T, for example your Query string. For each type that you want to pass to T, subclass your ObjectInfo<T> where T : Root class (e.g. create a class RootObjectInfo : ObjectInfo<RootObject> that overrides the Query property of ObjectInfo<T> to return the appropriate string). Then, modify Connect<T> so it requires an ObjectInfo<T> as an argument.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With