0

I have a base class with the following signature

public class ReportViewModelBaseDTO<VT,DT>

and concrete classes like these

public class ChartViewModelDTO:ReportViewModelBaseDTO<ChartViewModel,ChartViewModelDTO>

My question is, I know that the second type parameter of my generic base class should be the type of the concrete class. I don't want to repeat myself all the time by naming the class and then repeating that name as the type parameter.

Is there any way to have my generic base class take the actual concrete class as a type paramaeter? does anyone have any suggestions on better ways to do this?

EDIT:

an example of how I want to use DT is below. I create an instance of type DT from one of type VT thru Automapper.

public static DT Create(VT viewModel)
        {
            return Mapper.Map<VT,DT>(viewModel);   
        }
Greg Olmstead
  • 1,551
  • 10
  • 22
  • Can you supply a use case of how you want to use DT please? It feels a bit strange that the base class needs to know which concrete implementation it is the base class for. I can see a few uses (e.g. returning the correct type from a method) but not many. – Joey Oct 06 '11 at 17:00
  • 1
    C# does not have the means to enforce the requirement you appear to be going for, enforcing the generic T of the base class to be the type of the derived class. See [this related question](http://stackoverflow.com/questions/3783321/why-does-this-generic-constraint-compile-when-it-seems-to-have-a-circular-referen/3789193#3789193) for more. – Anthony Pegram Oct 06 '11 at 17:07

1 Answers1

1

Is this what you mean?

public class ReportViewModelBaseDTO<VT,DT> where DT : ReportViewModelBaseDTO<VT,DT>

Now your class 'knows' that the second type parameter is a concrete implementation of itself.

For your example method could you do:

public static DT Create(VT viewModel)
{
  return Mapper.Map<VT, DT>(viewModel);   
}

and define Mapper.Map as:

private U Map<T, U>(ViewModel viewModel) where U : ReportViewModelBaseDTO<T,U>{...}
Joey
  • 1,752
  • 13
  • 17
  • Does it *know*, or does it merely assume? Consider `class Animal where T : Animal { } class Cat : Animal { } class Dog : Animal { }` This is legal. C# does not have the means to enforce that only *Cat* can inherit from `Animal`. – Anthony Pegram Oct 06 '11 at 17:02
  • Not quite, I want my base class to know what type the derived class is, so that I can use that type in returning methods, such as the one in my edit – Greg Olmstead Oct 06 '11 at 17:19
  • Make Map generic, i.e. Mapper.Map(...) and then you can have Map return the correct type. – Joey Oct 06 '11 at 17:22
  • Lerxst... GetType() will return the type of class (not the base class)... ie public class Cat : Animal { ... } any code that calls GetType will return Cat as the type. – myermian Oct 06 '11 at 17:22
  • That's what I intended to do, but the method is static so I can't use GetType() – Greg Olmstead Oct 06 '11 at 17:27
  • changed my method to be generic just because it's easier but it's still the same problem – Greg Olmstead Oct 06 '11 at 17:35
  • As Anthony said you can't enforce that DT is sensible but provided you use it correctly Create will have a return type that is your concrete implementation. – Joey Oct 06 '11 at 17:38