C# 如何将静态字符串与对象类型C关联#

C# 如何将静态字符串与对象类型C关联#,c#,.net,generics,C#,.net,Generics,我有一个查询restAPI的方法,在这里我从JSON映射到一个对象。由于传递给此方法的查询字符串和对象类型必须始终匹配,因此我希望将查询字符串作为静态字符串包含 public class Root { public static string Query; } public class RootObject : Root, IRootObject { public D d { get; set; } public static new string Query = "A

我有一个查询restAPI的方法,在这里我从JSON映射到一个对象。由于传递给此方法的查询字符串和对象类型必须始终匹配,因此我希望将查询字符串作为静态字符串包含

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)
     }  
}
公共类根目录
{
公共静态字符串查询;
}
公共类RootObject:根,IRootObject
{
公共D{get;set;}
公共静态新字符串Query=“AccountSet”;
}
公共接口IRootObject
{
D{get;}
}
公共类RestClass
{
public void Connect(),其中T:Root,IRootObject
{    

T.Query您可以为此使用自定义属性:

[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;
    }
}
在课堂上使用它:

[Query("AccountSet")]
public class RootObject : Root, IRootObject
{
    public D d { get; set; }
}
并检索如下所示的值:

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

与C#和.NET CLI等语言相反,它们通常不支持静态多态性的概念

因此,您需要其他方式将特定于类型的信息附加到您的类型中,我建议使用以下两种方式:

  • 您可以使用标记类。该属性可以从
    typeof(T)中检索
    使用反射方法,例如。一旦定义了属性类,对于要传递给
    T
    的每个类型,这些属性都很容易声明。缺点是无法在编译时检查传递给
    T
    的每个类是否都有这样的属性修饰
  • 或者,您可以选择“信息对象”.创建一个基类
    ObjectInfo
    ,它作为类型
    T
    实例的工厂,并作为
    T
    上某些元信息的存储,例如您的
    查询
    字符串。对于要传递给
    T
    的每个类型,将
    ObjectInfo的子类化,其中T:Root
    类(例如,创建一个类
    RootObjectInfo:ObjectInfo
    ,该类重写
    ObjectInfo
    Query
    属性以返回适当的字符串)。然后,修改
    Connect
    ,使其需要一个
    ObjectInfo
    作为参数

  • 在C#(或者在一般的CLI中)中,虚拟静态成员的概念并不存在(不幸的是,IMO)。因此,您试图做的事情无法工作,因为
    T.Query
    (即使它是可编译的)将不会是多态的。您可以使用字符串参数编写自己的属性来标记类。F.e.
    [QueryName(“AccountSet”)]公共类RootObject…
    。然后您可以使用反射来提取字符串数据。如果您将查询属性的检索抽象为
    类型的扩展方法,代码可能会非常干净。@Baldrick您是对的。我对其进行了一点重构。在工具箱中使用这样的方法是个好主意。@Hmm这是编译的吗?不确定它会在一个非泛型类的中间使用<代码>类型(t)<代码>……@ BaldRyOOP,我复制/粘贴得太快了。谢谢!