222

I get a compile error

The type must be a reference type in order to use it as parameter 'T' in the generic type or method

on the 'Derived' class below. How to resolve this?

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

        }
    }
}
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
ChrisS
  • 2,595
  • 3
  • 18
  • 19

3 Answers3

497

I can't repro, but I suspect that in your actual code there is a constraint somewhere that T : class - you need to propagate that to make the compiler happy, for example (hard to say for sure without a repro example):

public class Derived<SomeModel> : Base<SomeModel> where SomeModel : class, IModel
                                                                    ^^^^^
                                                                 see this bit
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 12
    Thank you, yes that's it. Once I added the class constraint the compile error went away. The following seems to satisfy the need for refernce type. – ChrisS Jun 23 '11 at 08:33
  • here's what works. public class Base where T : class, IModel { public Base(IView view) { } } public class Derived : Base where SomeModel : class, IModel { public Derived(IView view) : base(view) { SomeModel m = (SomeModel)Activator.CreateInstance(typeof(SomeModel)); Service s = new Service(); s.Work(m); } } – ChrisS Jun 23 '11 at 08:34
  • Helped as well:) Thanks :) As a side note, I think we shouldn't copy the same constrait again and again if it's already applied in interface, IMO. – Celdor Nov 23 '14 at 20:09
48

You get this error if you have constrained T to being a class

thekip
  • 3,660
  • 2
  • 21
  • 41
10

If you put constrains on a generic class or method, every other generic class or method that is using it need to have "at least" those constrains.

Guish
  • 4,968
  • 1
  • 37
  • 39