Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast Generic<Derived> to Generic<Base> [duplicate]

I have a base WPF UserControl that handles some common functionality for derived UserControls. In the code-behind of any derived UserControl I call an event

private void SomeClick(object sender, RoutedEventArgs e) {
    HandleClick(sender);
    MyDataGrid.Items.Refresh();
}

In my base UserControl I do

public class BaseUserControl : UserControl {
   protected void HandleClick(object sender) {
       var vm = (BaseViewModel<Part>)DataContext;
       ...
   }
}

This throws an InvalidCastException since DataContext is of type BaseViewModel but of a derived type like BaseViewModel<Wire> or BaseViewModel<Connector>.

How can I cast that?

like image 228
juergen d Avatar asked Dec 16 '16 07:12

juergen d


People also ask

Is it possible to inherit from a generic type?

You can't inherit from a Generic type argument. C# is strictly typed language. All types and inheritance hierarchy must be known at compile time. . Net generics are way different from C++ templates.

What is generic MVC?

Generics introduces the concept of type parameters to .NET, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code.

What is a generic constraint?

The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.

Can generic be void?

Currently, void is not allowed as a generic parameter for a type or a method, what makes it hard in some cases to implement a common logic for a method, that's why we have Task and Task<T> for instance.


1 Answers

You cannot cast a Generic<Derived> to a Generic<Base>.

Just imagine if you could. You have a List<Wolf> and cast it to a List<Animal>. Now you could .Add() a Sheep to your List<Animal>. But wait... now your List<Wolf> contains a Sheep. What a mess.

This would only work out if you could make sure that the thing you cast to is read-only in all possible forms. This is was co- and contravariance is all about. It only works for interfaces though.

like image 65
nvoigt Avatar answered Sep 20 '22 22:09

nvoigt