How to derive type parameters with inherited types?

I have the following setup:

public abstract class super { }

public class sub : super { }

public static void Foo<T>(T element, Action<T> action)
    where T : new()
{ }

And I want to do this:

Action<super> superAction = (s) => { };
Foo(new sub(), superAction);

However, this fails because the second line is trying to call Foo<super>instead Foo<sub>. This will work:

Foo<sub>(new sub(), superAction);
  • Is it necessary in any case to display the type parameter in this case?
  • Why doesn't this infer the correct type in the first place?

EDIT:
The problem boils down to what is possible:

Action<sub> subAction = superAction;

But the compiler does not use this fact for output logic.
So, the answer to question 1:

Foo(new sub(), superAction as Action<sub>);

Question 2, why the compiler does not do this on its own, is still unresolved.

EDIT2:
2:
. , " " ( ). .
(, where, T : new()), .

+4
2

?

. - super. ? .

.

:

public static void Foo<T>(T element, Action<T> action) where T : new()

, :

  • , Ei U (Ei - T element), xi (xi - Foo<T> - , a U Ti.

, :

  • V Xi, U Xi.

, T Action<T>, :

  • , V C, i- C:
  • , .
  • , .
  • , .

:

  • Xi, (. 7.5.2.5), Xj (ยง7.5.2.10).

, :

Xi :

  • Uj Xi.

  • Xi : U Xi, Uj, U, . U Xi Uj U, . U Xi Uj, U, .

  • Uj V, , Xi V.

  • .

, super, sub T. , " ", , " " . :

A "bound" - , , "", "" "". , , T : , , Animal. , Animal " " ( - , , , ), - "" , . , , T , , , , , - ; . -, , , . -, , T Animal, , , , Animal . , . # , , , T . , (, , , !), . (*)

, " " :

, , , .

+3

, ( ) T.

:

Foo(new sub(), superAction as Action<sub>);

, T sub, .

:

Foo(new sub(), superAction);

, T super ( , Action<super> ), , new. T super, new ( abstract , new ed).

, :

Foo<sub>(new sub(), superAction);

, . Action<T> , T sub, Action<super> Action<sub>.

+1

Source: https://habr.com/ru/post/1612199/


All Articles