【问题标题】:Creating a generic method in C# through specific where clause通过特定的 where 子句在 C# 中创建泛型方法
【发布时间】:2018-12-30 12:19:20
【问题描述】:

我想创建一些通用方法,如下面的代码:

public async Task<T> Get<T>(string url) where T : IBaseModel, IList<IBaseModel>

显然我想支持可枚举集合以及从IBaseModel 接口驱动的单个对象。 方法定义没问题,但是在使用时我会收到以下错误:

await myClass.Get<List<DrivedClassFromBaseModel>>("some url");

There is no implicit conversion from "System.Collection.Generic.List<DrivedClassFromBaseModel> to System.Collection.Generic.IList<IBaseModel>"

【问题讨论】:

  • 您不能将派生类型的列表转换为具有基类的列表。这将允许将具有相同基类的其他类型添加到该列表中。
  • List&lt;DrivedClassFromBaseModel&gt; 怎么可能是IBaseModel
  • 你应该可以做 Task> Get(string url) where T : IBaseModel
  • @Reza Aghaei DrivedClassFromBaseModel:IBaseModel
  • 我明白了,但DrivedClassFromBaseModel:IBaseModel 并不意味着List&lt;DrivedClassFromBaseModel&gt;IBaseModel。正如答案中已经提到的那样,where T : IBaseModel, IList&lt;IBaseModel&gt; 意味着T 应该同时实现IBaseModelIList&lt;IBaseModel&gt;

标签: c# .net generics generic-collections generic-constraints


【解决方案1】:

Generic constraints 将通过 AND 组合,因此 where T : IBaseModel, IList&lt;IBaseModel&gt; 意味着 T 应该同时实现 IBaseModelIList&lt;IBaseModel&gt;

你需要创建两个方法:

public async Task<T> Get<T>(string url) where T : IBaseModel
public async Task<IList<T>> GetList<T>(string url) where T : IBaseModel

【讨论】:

  • 如果这两个方法是同一类的成员,可以将&lt;T&gt;作为通用泛型约束,请将T移动到类的泛型参数中。
【解决方案2】:

你可以使用另一个实现了 IBaseModel 和 IList 的类,然后 T 被约束到这个类。

public class DerivedModel : IBaseModel, IList<IBaseModel>
{
    private int _size;
    private IBaseModel[] _items=new IBaseModel[1000];
    private int _version;
    public int Id { get; set; }
    public IEnumerator<IBaseModel> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
...
}

而通用方法是:

public async Task<T> Get<T>(string url) where T : DerivedModel 
    {
        return await Task<T>.Factory.StartNew(() =>
        {
            var derivedModel = new DerivedModel() {new BaseModel() {Id = 1}};
            return (T) derivedModel;
        });
    }

IBaseModel和BaseModel可以在其中:

public interface IBaseModel
{
    int Id { get; set; }
}

public class BaseModel : IBaseModel
{
    public int Id { get; set; }
}

用法:

var inheritance=new Inheritance();
var result = await inheritance.Get<DerivedModel>("aaa");
textBox1.Text = result[0].Id.ToString();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2021-02-18
    相关资源
    最近更新 更多