visual tipos tipo studio programacion locales las inicializar implícito explícito deben datos conversion con c# .net generics .net-2.0 delegates

studio - tipos de datos en c# pdf



La diferencia entre la creación delegada implícita y explícita(con y sin genéricos) (3)

Vea las cuatro líneas en el método Go () a continuación:

delegate void Action<T>(T arg); delegate void Action(); void DoSomething<T>(Action<T> action) { //... } void DoSomething(Action action) { //... } void MyAction<T>(T arg) { //... } void MyAction() { //... } void Go<T>() { DoSomething<T>(MyAction<T>); // throws compiler error - why? DoSomething(new Action<T>(MyAction<T>)); // no problems here DoSomething(MyAction); // what''s the difference between this... DoSomething(new Action(MyAction)); // ... and this? }

Tenga en cuenta que el error de compilación generado por la primera llamada es: Los argumentos de tipo para el método ''Acción (T)'' no se pueden deducir del uso. Intente especificar los argumentos de tipo explícitamente.


La creación delegada implícita no genérica es solo azúcar sintáctica, por lo que el compilador genera exactamente el mismo código para

DoSomething(MyAction);

y

DoSomething(new Action(MyAction));

ya que puede inferir el tipo de delegado directamente del método argumentos y contexto.

Con el delegado genérico, debe especificar el tipo de delegado debido a la covarianza y la contradicción (consulte http://msdn.microsoft.com/en-us/library/ms173174(VS.80).aspx para obtener más información): la T en La acción puede ser un supertipo de la T en el método, y aún se aceptará como un método delegado. Entonces, necesita especificar la T en el delegado explícitamente ya que el compilador no puede resolverlo por sí mismo.


No hay diferencia entre MyAction y la new Action(MyAction) (cuando ambas son válidas) distintas a la anterior que no funcionarán en C # 1. Esta es una implicit method group conversion . Hay momentos en que esto no es aplicable, más notable cuando el compilador no puede determinar qué tipo de delegado desea, por ejemplo

Delegate foo = new Action(MyAction); // Fine Delegate bar = MyAction; // Nope, can''t tell target type

Esto entra en juego en su pregunta porque ambos métodos están sobrecargados. Esto lleva a dolores de cabeza, básicamente.

En cuanto al lado de los genéricos, es interesante. Los grupos de métodos no reciben mucho amor de la inferencia de tipo C # 3: no estoy seguro de si se mejorará en C # 4 o no. Si llama a un método genérico y especifica el argumento de tipo, la inferencia de tipo funciona bastante bien, pero si intenta hacerlo al revés, falla:

using System; class Test { static void Main() { // Valid - it infers Foo<int> DoSomething<int>(Foo); // Valid - both are specified DoSomething<int>(Foo<int>); // Invalid - type inference fails DoSomething(Foo<int>); // Invalid - mismatched types, basically DoSomething<int>(Foo<string>); } static void Foo<T>(T input) { } static void DoSomething<T>(Action<T> action) { Console.WriteLine(typeof(T)); } }

La inferencia de tipo en C # 3 es muy complicada y funciona bien en la mayoría de los casos (en particular, es excelente para LINQ) pero falla en algunos otros. En un mundo ideal, sería más fácil de entender y más poderoso en futuras versiones ... ¡ya veremos!


Solo una nota al margen ... Por alguna razón esto funciona en VB.

Parece que la implementación del preprocesador en C # y VB difiere cuando trato de convertir el Methodgroup / adderessof a un delegado.