Typ musi być typem odniesienia, aby można go było używać jako parametru „T” w typie lub metodzie ogólnej


211

Zagłębiam się w generyczne i teraz mam sytuację, w której potrzebuję pomocy. Otrzymuję błąd kompilacji w poniższej klasie „Derived”, jak pokazano w tytule tematu. Widzę wiele innych postów podobnych do tego, ale nie widzę związku. Czy ktoś może mi powiedzieć, jak to rozwiązać?

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)
        {

        }
    }
}

Nie otrzymuję żadnych błędów kompilacji
Vince Panuccio,

Ten kod nie pokazuje tego błędu. Kompiluje się czysto.
Marc Gravell

Odpowiedzi:


474

Nie mogę repro, ale podejrzewam, że w twoim kodzie jest jakieś ograniczenie, które T : class- na przykład, musisz rozpropagować to, aby uszczęśliwić kompilator (trudno powiedzieć na pewno bez przykładu repro):

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

12
Dziękuję, tak to jest to. Po dodaniu ograniczenia klasy błąd kompilacji zniknął. Poniższe wydaje się zaspokajać potrzebę typu refernce.
ChrisS,

oto co działa. klasa publiczna Baza <T> gdzie T: klasa, IModel {baza publiczna (IView <T> widok) {}} klasa publiczna Pochodna <SomeModel>: Baza <SomeModel> gdzie SomeModel: klasa, IModel {public Pochodna (IView <SomeModel> view): base (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Usługa <SomeModel> s = nowa usługa <SomeModel> (); s.Work (m); }}
ChrisS

Pomagał również :) Dzięki :) Na marginesie uważam, że nie powinniśmy kopiować tej samej konstelacji raz po raz, jeśli jest już zastosowana w interfejsie IMO.
Celdor

46

Ten błąd Tpojawia się, jeśli ograniczyłeś się do byciaclass


9

Jeśli nałożysz ograniczenia na ogólną klasę lub metodę, każda inna generyczna klasa lub metoda, która jej używa, musi mieć „co najmniej” te ograniczenia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.