Тип повинен бути еталонним типом, щоб використовувати його як параметр '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)
        {

        }
    }
}

Я не отримую жодних помилок компіляції
Вінс Пануччо,

Цей код не відображає цієї помилки. Компілюється чисто.
Марк Гравелл

Відповіді:


474

Я не можу спростувати, але я підозрюю, що у вашому фактичному коді десь є обмеження, яке T : classвам потрібно поширити, щоб зробити компілятор щасливим, наприклад (важко сказати точно без прикладу репро):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit

12
Дякую, так, це все. Як тільки я додав обмеження класу, помилка компіляції усунулася. Наступне, здається, задовольняє потребу в типі референції.
ChrisS

ось що працює. публічний клас Base <T> де T: клас, IModel {public Base (IView <T> перегляд) {}} публічний клас Похідний <SomeModel>: База <SomeModel>, де SomeModel: клас, IModel {public Derived (IView <SomeModel> view): база (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Сервіс <SomeModel> s = новий Сервіс <SomeModel> (); с.Робота (м); }}
ChrisS

Допомагав також :) Спасибі :) Як бічна примітка, я думаю, що ми не повинні копіювати один і той же обмеження знову і знову, якщо це вже застосовано в інтерфейсі, IMO.
Celdor

46

Ви отримуєте цю помилку, якщо обмежились Tтим, що єclass


9

Якщо ви ставите обмеження на загальний клас чи метод, кожен інший родовий клас чи метод, який його використовує, повинні мати "принаймні" ці обмеження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.