Создание универсального метода в C # через конкретное предложение where - PullRequest
0 голосов
/ 30 декабря 2018

Я хочу создать несколько общих методов, таких как код ниже:

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 ]

0 голосов
/ 31 декабря 2018

Вы можете использовать другой класс, который реализует как 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();
0 голосов
/ 30 декабря 2018

Общие ограничения будут объединены с помощью AND, поэтому 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
...