通用方法给出了错误

时间:2016-05-12 19:34:25

标签: c# generics

我试图为下面提到的代码片段编写一个通用方法。但它在OrderBy子句上给出错误?你能告诉我为什么吗?

var cache = RedisConnectorHelper.Connection.GetDatabase();
var values = JsonConvert.DeserializeObject<List<StateListDto>>(cache.StringGet(AppConsts.States));
if (values != null) return new ListResultOutput<StateListDto>(values.OrderBy(o => o.Name).ToList());

通用方法:

 public ListResultOutput<T> GetCache<T>(string cacheKey)
   {
      var cache = RedisConnectorHelper.Connection.GetDatabase();
      var values = JsonConvert.DeserializeObject<List<T>>(cache.StringGet(cacheKey));
      return values != null ? new ListResultOutput<T>(values.ToList().OrderBy(o=>o.Name)) : null;
   }

致电:

var values = GetCache<StateListDto>(AppConsts.States);

StateListDto.cs

 public class StateListDto 
    {
        public string Code { get; set; }
        public string Name { get; set; }
    }

它出现此错误: (点击查看完整大小的图片)

enter image description here

3 个答案:

答案 0 :(得分:2)

如果您希望将其用于FTPSClient以上,我建议创建一个具有StateListDto属性的接口或基类,那么您可以保证它存在。

类似的东西:

Name

然后您可以将方法更改为:

public interface IDto
{
    string Name { get; }
}

答案 1 :(得分:1)

  

但是所有人都有Name属性。

然后为他们创建一个通用界面,如下所示:

public interface INamed
{
    string Name { get; }
}

具有该属性的所有模型都可以实现该接口:

public class StateListDto : INamed

然后,您可以将该接口用作泛型方法的类型约束:

public ListResultOutput<T> GetCache<T>(string cacheKey) where T: INamed

这样编译器就可以保证T的类型具有Name属性。

请注意,也可以使用基类(具体或抽象)来实现此目的。虽然我个人更喜欢使用接口而不是继承,除非有特定的理由使用继承。

答案 2 :(得分:1)

您可以按照以下参数发送您想要订购的方式:

public ListResultOutput<T> GetCache<T>(string cacheKey, Func<T,object> selector)
{
    var cache = RedisConnectorHelper.Connection.GetDatabase();
    var values = JsonConvert.DeserializeObject<List<T>>(cache.StringGet(cacheKey));
    return values != null ? new ListResultOutput<T>(values.OrderBy(selector).ToList()) : null;
}

致电:

GetCache<StateListDto>("yourKey", i=>i.Name);

通过这种方式,您不会强制您的类实现任何内容 - 您可以选择按代码中的其他参数进行排序