GrayFox
GrayFox

Reputation: 1089

Understanding generic compile error

I have 2 abstract classes:

BasePoco:

public abstract class BasePoco
{
    public BasePoco(){}
  // Properties etc...
}

BaseViewModel:

public abstract class BaseViewModel<T> where T : BasePoco, new()
{
  // ViewModel stuff...
}

If I try something like this:

            var baseViewModel = currentView.DataContext as BaseViewModel<BasePoco>;
            if (baseViewModel != null)
                baseViewModel.Dispose();

I always get the following compiler error:

The type 'BasePoco' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'BaseViewModel' in the generic type or method 'generic'

I don't know why, could you explain and how to fix this?

Upvotes: 0

Views: 123

Answers (2)

Vadim Martynov
Vadim Martynov

Reputation: 8892

It's because public constructor of abstract class is not fully public because you can't call it directly. One of the possible fixes is to delete new() constraint from your ViewModel if it's not necessary.

public abstract class BaseViewModel<T> where T : BasePoco
{
    // ViewModel stuff...
}

The other option is to have non-geric class with Dispose() method:

public abstract class BaseViewModel
{
    public void Dispose() {} // or abstract method
}

public abstract class BaseViewModel<T> : BaseViewModel 
    where T : BasePoco, new()
{
    // ViewModel stuff...
}

var baseViewModel = currentView.DataContext as BaseViewModel;
if (baseViewModel != null)
    baseViewModel.Dispose();

Upvotes: 1

Yacoub Massad
Yacoub Massad

Reputation: 27861

I don't know why, could you explain

The problem is that BaseViewModel has a constraint on T that T can be constructed via new T(). Since BasePoco is abstract, then it cannot be constructed via new BasePoco(). Therefore, BaseViewModel<BasePoco> is not a valid type.

how to fix this?

Since all what you are doing is disposing the object, then you can cast it to IDisposable like this:

var disposable = currentView.DataContext as IDisposable;
if (disposable != null)
    disposable.Dispose();

Upvotes: 2

Related Questions