Los genéricos de c# no pueden inferir un segundo parámetro?

Esta pregunta ya tiene una respuesta aquí:            >            Why must I provide explicitly generic parameter types While the compiler should infer the type?                                    2 respuestas                                He notado que el compilador de c# no infiere el segundo parámetro genérico.
Ejemplo:

Código de la plantilla C: (sí, sé que las plantillas no funcionan como los genéricos)

class Test {
public:
template <class T,class V> 
    T test(V v) {
       //do something with v
       return T();
    }
};

int i = 0;
Test t = new Test();
double j = t.test<double>(i); //infers V as int

Las plantillas (y los genéricos) no pueden inferir el tipo de retorno, por lo que en C le doy el primer parámetro de plantilla y el segundo parámetro de plantilla se deduce del tipo de variable.

Ahora, el mismo ejemplo en c#:

class Test {
    public T test<T,V>(V v) where T: new() {
       //do something with v
       return new T();
    }
};

int i = 0;
Test t = new Test();
double j = t.test<double>(i); //Error Using the generic method 'Test.test<T,V>(V)' requires '2' type arguments

Pero si uso 1 tipo, no tengo que especificar explícitamente el tipo:

class Test {
    public V test<V>(V v) where V: new() {
       return new V();
    }
};

int i = 0;
Test t = new Test();
int j = t.test(i); //OK infers V as int.

Entonces, ¿por qué los genéricos c# no pueden inferir el segundo tipo (mientras que en las plantillas c claramente puede)?
Estoy seguro de que está diseñado de esa manera (dudo que el equipo de .Net haya pasado esto por alto), entonces, ¿por qué está diseñado de esta manera que debo especificar explícitamente ambos tipos?

Editar:

De las discusiones que tuvimos en las respuestas hasta el momento, ambos idiomas admiten la sobrecarga por el número de parámetros de la plantilla.

Así que de nuevo, ¿por qué c# está diseñado de esta manera? ¿Qué es diferente en la implementación del lenguaje que no permite declarar explícitamente solo un parámetro?

c# ha sido diseñado para ser un lenguaje un poco menos complejo que C.

En particular, no creo que sea una buena idea comparar los genéricos de c# con las plantillas de C por varias razones: son básicamente dos enfoques muy diferentes para lograr cosas similares en algunas situaciones. El enfoque de C es ciertamente flexible en algunos aspectos, aunque no permite (como yo lo entiendo) plantillas que solo existen en forma binaria, o que se creen nuevas especializaciones de plantillas en el momento de la ejecución. Básicamente, el enfoque de la plantilla en C no encaja bien con el resto de cómo encaja .NET.

Ahora, por qué no puede especificar algunos argumentos de tipo y permitir que se deduzcan otros (que es una decisión de lenguaje en lugar de una decisión de plataforma; estoy seguro de que sería factible en lo que respecta a .NET en sí). Creo que esto es por simplicidad. Elegir el método correcto exacto y los argumentos de tipo correcto ya es extremadamente complicado en c#: es más complicado de lo que la mayoría de los desarrolladores de c# pueden dar la vuelta. Se trata de:

> Potencialmente considerando métodos para la jerarquía de tipos del tipo de destino en tiempo de compilación
> Sobrecarga por número de parámetros
> Sobrecarga por el número de parámetros tipo
> El efecto de los argumentos con nombre
> El efecto de los parámetros opcionales.
> El efecto de las restricciones de parámetros de tipo genérico en los tipos de parámetros (no restricciones especificadas por el método de destino, nota)
> Grupo de métodos para delegar conversiones.
> Conversiones de funciones anónimas
> Inferencia de tipo para argumentos de tipo
> Escritura dinámica
> Covarianza genérica y contravarianza

Personalmente, creo que eso es suficiente para entenderlo, sin permitir aún más posibilidades a través de “M puede ser un candidato si tiene al menos tantos parámetros de tipo como argumentos de tipo especificado”. ¿También querría argumentos de tipo con nombre y parámetros de tipo opcionales? 😉

He analizado la sobrecarga bastante, siguiendo las especificaciones a fondo, etc. He encontrado áreas que hacen que los diseñadores de idiomas se rasquen la cabeza e intenten averiguar qué debe hacer el compilador. He encontrado áreas en las que el compilador definitivamente se equivoca. No me gustaría agregar más complejidad aquí sin una buena razón.

Así que sí, es básicamente por simplicidad, y a veces eso es un dolor, pero a menudo puedes evitarlo. Para cada característica potencial, debe tener en cuenta:

> El beneficio de la característica para los desarrolladores finales.
> El costo de la función para los desarrolladores finales en términos de tiempo dedicado a entenderlo
> El costo para los diseñadores de idiomas en el diseño y la especificación a fondo.
> El costo para los escritores del compilador al implementarlo correctamente.
> El costo para el equipo de pruebas al probarlo a fondo (junto con todo lo demás relacionado con la sobrecarga)
> El costo de las funciones potenciales futuras (si esto hace que el lenguaje sea más complicado, eso deja menos complejidad adicional “potencialmente exigible” para otras funciones)

Por favor indique la dirección original:Los genéricos de c# no pueden inferir un segundo parámetro?