Тип должен быть ссылочным типом, чтобы использовать его в качестве параметра 'T' в универсальном типе или методе.

211

Я углубляюсь в дженерики, и теперь у меня возникла ситуация, в которой мне нужна помощь. Я получаю ошибку компиляции в классе «Производные» ниже, как показано в заголовке темы. Я вижу много других сообщений, похожих на этот, но я не вижу отношений. Может кто-нибудь сказать мне, как решить эту проблему?

using System;
using System.Collections.Generic;


namespace Example
{
    public class ViewContext
    {
        ViewContext() { }
    }

    public interface IModel
    {
    }

    public interface IView<T> where T : IModel 
    {
        ViewContext ViewContext { get; set; }
    }

    public class SomeModel : IModel
    {
        public SomeModel() { }
        public int ID { get; set; }
    }

    public class Base<T> where T : IModel
    {

        public Base(IView<T> view)
        {
        }
    }

    public class Derived<SomeModel> : Base<SomeModel> where SomeModel : IModel
    {

        public Derived(IView<SomeModel> view)
            : base(view)
        {
            SomeModel m = (SomeModel)Activator.CreateInstance(typeof(SomeModel));
            Service<SomeModel> s = new Service<SomeModel>();
            s.Work(m);
        }
    }

    public class Service<SomeModel> where SomeModel : IModel
    {
        public Service()
        {
        }

        public void Work(SomeModel m)
        {

        }
    }
}
Chriss
источник
Я не получаю ошибок компиляции
Vince Panuccio
Этот код не показывает эту ошибку. Компилируется чисто.
Марк Гравелл

Ответы:

474

Я не могу воспроизвести, но я подозреваю, что в вашем реальном коде есть где-то ограничение T : class- вам нужно распространять это, например, чтобы компилятор был доволен (трудно сказать наверняка без примера с репро):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit
Марк Гравелл
источник
12
Спасибо, да это все. Как только я добавил ограничение класса, ошибка компиляции исчезла. Следующее, кажется, удовлетворяет потребность в типе ссылки.
ChrisS
вот что работает. общедоступный класс Base <T>, где T: класс, IModel {общедоступная база (IView <T> представление) {}} общедоступный класс Derived <SomeModel>: Base <SomeModel>, где SomeModel: класс, IModel {общедоступный Derived (IView <SomeModel> view): base (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Сервис <SomeModel> s = новый Сервис <SomeModel> (); s.Work (м); }}
ChrisS
Также помогло :) Спасибо :) Как примечание, я думаю, что мы не должны копировать тот же самый договор снова и снова, если он уже применен в интерфейсе, IMO.
Селдор
46

Вы получаете эту ошибку , если вы ограничены , Tчтобы бытьclass

thekip
источник
9

Если вы наложите ограничения на универсальный класс или метод, каждый другой универсальный класс или метод, который их использует, должен иметь «хотя бы» эти ограничения.

сящийся
источник