Il tipo deve essere un tipo di riferimento per usarlo come parametro 'T' nel tipo o metodo generico


211

Mi sto approfondendo con i generici e ora ho una situazione in cui ho bisogno di aiuto. Viene visualizzato un errore di compilazione nella classe "Derivata" di seguito, come mostrato nel titolo del soggetto. Vedo molti altri post simili a questo, ma non vedo la relazione. Qualcuno può dirmi come risolverlo?

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

        }
    }
}

Non ottengo errori di compilazione
Vince Panuccio,

Questo codice non mostra questo errore. Compila in modo pulito.
Marc Gravell

Risposte:


474

Non posso riproporre, ma sospetto che nel tuo codice reale ci sia un vincolo da qualche parte che T : class- devi propagarlo per rendere felice il compilatore, per esempio (difficile da dire senza un esempio di repro):

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

12
Grazie, sì, è tutto. Una volta aggiunto il vincolo di classe, l'errore di compilazione è scomparso. Quanto segue sembra soddisfare la necessità del tipo di riferimento.
ChrisS,

ecco cosa funziona. public class Base <T> dove T: class, IModel {public Base (IView <T> view) {}} public class Derivato <SomeModel>: Base <SomeModel> dove SomeModel: class, IModel {public Derived (IView <SomeModel> view): base (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Service <SomeModel> s = new Service <SomeModel> (); s.Work (m); }}
ChrisS,

Aiutato anche :) Grazie :) Come nota a margine, penso che non dovremmo copiare lo stesso stretto più e più volte se è già applicato nell'interfaccia, IMO.
Celdor,

46

Questo errore viene visualizzato se si è costretti Ta essere aclass


9

Se si applicano vincoli a una classe o a un metodo generico, ogni altra classe o metodo generico che lo utilizza deve disporre di "almeno" tali vincoli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.