Le type doit être un type de référence pour pouvoir l'utiliser comme paramètre 'T' dans le type ou la méthode générique

211

J'approfondis les génériques et j'ai maintenant une situation avec laquelle j'ai besoin d'aide. J'obtiens une erreur de compilation sur la classe «dérivée» ci-dessous, comme indiqué dans le titre du sujet. Je vois beaucoup d'autres messages similaires à celui-ci mais je ne vois pas la relation. Quelqu'un peut-il me dire comment résoudre ce problème?

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
la source
Je ne reçois aucune erreur de compilation
Vince Panuccio
Ce code ne montre pas cette erreur. Compile proprement.
Marc Gravell

Réponses:

474

Je ne peux pas reprocher, mais je soupçonne que dans votre code actuel il y a une contrainte quelque part qui T : class- vous devez propager cela pour rendre le compilateur heureux, par exemple (difficile à dire avec certitude sans exemple de repro):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit
Marc Gravell
la source
12
Merci, oui c'est ça. Une fois que j'ai ajouté la contrainte de classe, l'erreur de compilation a disparu. Ce qui suit semble satisfaire le besoin d'un type de référence.
ChrisS
voici ce qui fonctionne. classe publique Base <T> où T: classe, IModel {public Base (IView <T> vue) {}} classe publique Derived <SomeModel>: Base <SomeModel> où SomeModel: class, IModel {public Derived (IView <SomeModel> vue): base (vue) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Service <SomeModel> s = nouveau Service <SomeModel> (); s.Travail (m); }}
ChrisS
Aidé aussi :) Merci :) En remarque, je pense que nous ne devrions pas copier le même constrait encore et encore s'il est déjà appliqué dans l'interface, IMO.
Celdor
46

Vous obtenez cette erreur si vous êtes contraint Td'être unclass

thekip
la source
9

Si vous placez des contraintes sur une classe ou une méthode générique, toutes les autres classes ou méthodes génériques qui l'utilisent doivent avoir "au moins" ces contraintes.

Guish
la source