El tipo debe ser un tipo de referencia para usarlo como parámetro 'T' en el tipo o método genérico


211

Estoy profundizando en los genéricos y ahora tengo una situación en la que necesito ayuda. Recibo un error de compilación en la clase 'Derivada' a continuación, como se muestra en el título del tema. Veo muchas otras publicaciones similares a esta, pero no veo la relación. ¿Alguien puede decirme cómo resolver esto?

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

        }
    }
}

No recibo ningún error de compilación
Vince Panuccio

Este código no muestra ese error. Compila limpiamente.
Marc Gravell

Respuestas:


474

No puedo reprobar, pero sospecho que en su código real hay una restricción en algún lugar que T : classnecesita propagar para hacer feliz al compilador, por ejemplo (difícil de decir con certeza sin un ejemplo de repro):

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

12
Gracias, sí, eso es. Una vez que agregué la restricción de clase, el error de compilación desapareció. Lo siguiente parece satisfacer la necesidad del tipo de referencia.
ChrisS

Esto es lo que funciona. public class Base <T> donde T: class, IModel {public Base (IView <T> view) {}} public class Derived <SomeModel>: Base <SomeModel> donde SomeModel: class, IModel {public Derived (IView <SomeModel> view): base (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Servicio <SomeModel> s = nuevo Servicio <SomeModel> (); s.Trabajo (m); }}
ChrisS

También ayudó :) Gracias :) Como nota al margen, creo que no deberíamos copiar la misma restricción una y otra vez si ya está aplicada en la interfaz, IMO.
Celdor el

46

Obtiene este error si se ha limitado Ta ser unclass


9

Si coloca restricciones en una clase o método genérico, cualquier otra clase o método genérico que lo esté utilizando debe tener "al menos" esas restricciones.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.