Тип должен быть ссылочным типом, чтобы использовать его в качестве параметра '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)
        {

        }
    }
}

Я не получаю ошибок компиляции
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


9

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.