通用类误解

时间:2018-04-29 23:46:41

标签: c#

来自php我是C#的新手 我想创建一个Store,它将所有数据保存在一个有组织但模块化/通用的结构中。因此,我有一个类Store从api获取数据并应将其存储到本地RecordStore:

class Store
{
     public static T FindRecord<T>(Type ModelType, int id)
     {
            RestClient rClient = new RestClient();
            Debug.WriteLine("making request to: " + ModelType.Name.ToLower() + "/" + id);
            string response = rClient.makeRequest(ModelType.Name.ToLower()+"/"+id);
            JObject Payload = JObject.Parse(response);
            T model = JsonConvert.DeserializeObject<T>(Payload[ModelType.Name.ToLower()].ToString());
            // all good til there
            // but HERE'S THE PROBLEM:
            RecordStore.PushItem(ModelType, model);
            return model;
     }
}

class RecordStore
{
    protected static List<BaseModel> Models;
    // I can't do that:
    // protected static List<T> Models;

    public static void PushItem<T>(Type ModelType, T Item)
    {
        Console.WriteLine("pushing ModelType: "+ModelType.ToString());
        Models.Add(Item); // na, that won't work: "Converting from "T" to "BaseModel" not possible
    }
}

所有这些都是从Main调用的:

Production Production = Store.FindRecord<Production>(typeof(Production), id: 3);

Production是一个扩展BaseModel的简单类,没有什么特别之处。只是描述模型的一些属性 RestClient是另一个简单的类,它调用我的Api来获取数据为json。

所以,问题是:我对通用属性/方法有什么误解?我究竟做错了什么?是否有一个简单的解决方案来完成我想要做的事情?

1 个答案:

答案 0 :(得分:4)

你的问题主要是限制因素。但是请看一下以下的重构

public class BaseModel
{
    ///
}

public class RecordStore
{
   protected static List<BaseModel> Models;

   public static void PushItem<T>(T item)
      where T : BaseModel
   {
      var modelType = typeof(T);
      Console.WriteLine("pushing ModelType: " + modelType.ToString());
      Models.Add(item);
   }
}

public class Store
{
   public static T FindRecord<T>(int id)
      where T : BaseModel
   {
      var modelType = typeof(T);
      var rClient = new RestClient();
      Debug.WriteLine($"making request to: {modelType.Name.ToLower()}/{id}");
      var response = rClient.makeRequest($"{modelType.Name.ToLower()}/{id}");
      var payload = JObject.Parse(response);

      var model = JsonConvert.DeserializeObject<T>(
         payload[modelType.Name.ToLower()]
           .ToString());

      RecordStore.PushItem(model);

      return model;
   }
}

进一步阅读

Constraints on type parameters (C# Programming Guide)

  

约束通知编译器类型参数的功能   一定有。没有任何约束,类型参数可以是任何   类型。编译器只能承担Object的成员,即   任何.NET类型的终极基类