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

        }
    }
}

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

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


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.