代码之家  ›  专栏  ›  技术社区  ›  Saman Gholami

通过特定where子句在C#中创建泛型方法

  •  2
  • Saman Gholami  · 技术社区  · 7 年前

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

    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>"
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   Reza Aghaei    6 年前

    Generic constraints 将由和合并,所以 where T : IBaseModel, IList<IBaseModel> 方法 T 两者都应该实现 IBaseModel IList<IBaseModel> .

    您需要创建两个方法:

    public async Task<T> Get<T>(string url) where T : IBaseModel
    public async Task<IList<T>> GetList<T>(string url) where T : IBaseModel
    
        2
  •  0
  •   Vahid Asbaghi    7 年前

    您可以使用另一个同时实现iAsseModel和IList的类,然后将IList约束到这个类。

    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();