O tipo deve ser um tipo de referência para usá-lo como parâmetro 'T' no tipo ou método genérico

211

Estou aprofundando os genéricos e agora tenho uma situação em que preciso de ajuda. Eu recebo um erro de compilação na classe 'Derivado' abaixo, como mostrado no título do assunto. Vejo muitos outros posts semelhantes a este, mas não estou vendo o relacionamento. Alguém pode me dizer como resolver isso?

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
fonte
Eu não recebo nenhum erro de compilação
Vince Panuccio 23/06
Este código não mostra esse erro. Compila de forma limpa.
Marc Gravell

Respostas:

474

Não consigo reproduzir, mas suspeito que no seu código real há uma restrição em algum lugar que T : class- você precisa propagá-lo para deixar o compilador feliz, por exemplo (difícil dizer com certeza sem um exemplo de reprodução):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit
Marc Gravell
fonte
12
Obrigado, sim, é isso. Depois de adicionar a restrição de classe, o erro de compilação desapareceu. O seguinte parece satisfazer a necessidade do tipo de referência.
ChrisS
aqui está o que funciona. public class Base <T> onde T: class, IModel {public Base (IView <T> view) {}} public class Derived <SomeModel>: Base <SomeModel> onde SomeModel: class, IModel {public Derived (IView <SomeModel> view): base (view) {SomeModel m = (SomeModel) Activator.CreateInstance (typeof (SomeModel)); Service <SomeModel> s = novo Serviço <SomeModel> (); s.Trabalho (m); }}
ChrisS
Ajudou também :) Obrigado :) Como observação, acho que não devemos copiar o mesmo construto repetidas vezes, se já estiver aplicado na interface, IMO.
Celdor #
46

Você recebe esse erro se tiver restringido Ta ser umclass

thekip
fonte
9

Se você colocar restrições em uma classe ou método genérico, todas as outras classes ou métodos genéricos que estiverem em uso precisarão ter "pelo menos" essas restrições.

Guish
fonte