visual usos programacion metodos historicos definicion clases características antecedentes c# .net generics extension-methods anonymous-types

usos - clases y metodos en c#



Tipos anónimos: ¿hay alguna característica especial? (3)

A los efectos de los métodos de extensión, no hay forma de distinguir un tipo anónimo. Los métodos de extensión funcionan especificando un método para un tipo de nombre de tiempo de compilación. Los tipos anónimos no son identificables y, por lo tanto, no son visibles en el momento de la compilación. Esto los hace incompatibles con los métodos de extensión.

¿Hay algo que usar para determinar si un tipo es realmente de tipo anónimo? Por ejemplo, una interfaz, etc.

El objetivo es crear algo como lo siguiente ...

//defined like... public static T Get<T>(this IAnonymous obj, string prop) { return (T)obj.GetType().GetProperty(prop).GetValue(obj, null); } //... //And then used like... var something = new { name = "John", age = 25 }; int age = something.Get<int>("age");

¿O es solo la belleza de un tipo anónimo? ¿Nada para identificarse porque toma una nueva forma?

Nota : me doy cuenta de que puede escribir un método de extensión para la clase de objeto , pero eso parece un poco exagerado, en mi opinión.


EDITAR: La lista a continuación se aplica a los tipos anónimos de C #. VB.NET tiene reglas diferentes, en particular, puede generar tipos anónimos mutables (y lo hace de forma predeterminada). Jared ha señalado en el comentario que el estilo de nombre es diferente también. Básicamente todo esto es bastante frágil ...

No puede identificarlo en una restricción genérica, pero:

  • Será una clase (en lugar de interfaz, enum, struct, etc.)
  • Tendrá aplicado el CompilerGeneratedAttribute
  • Anulará Equals, GetHashCode y ToString
  • Estará en el espacio de nombres global
  • No se anidará en otro tipo
  • Será interno
  • Estará sellado
  • Derivará directamente del object
  • Será genérico con tantos parámetros de tipo como propiedades. (Puede tener un tipo anónimo no genérico, sin propiedades. Sin embargo, es un poco inútil).
  • Cada propiedad tendrá un parámetro de tipo con un nombre que incluye el nombre de la propiedad, y será de ese tipo, por ejemplo, la propiedad Name se convierte en una propiedad de tipo <> _ Name
  • Cada propiedad será pública y de solo lectura
  • Para cada propiedad habrá un campo privado readonly correspondiente
  • No habrá otras propiedades o campos
  • Habrá un constructor tomando un parámetro correspondiente a cada parámetro de tipo, en el mismo orden que los parámetros de tipo
  • Cada método y propiedad tendrá el DebuggerHiddenAttribute aplicado.
  • El nombre del tipo comenzará con "<>" y contendrá "AnonymousType"

Muy poco de esto está garantizado por la especificación, sin embargo, por lo que todo podría cambiar en la próxima versión del compilador, o si usa Mono, etc.


Según recuerdo, hay un marcador CompilerGeneratedAttribute ... 2 segundos

Además, el nombre será raro, y será un tipo genérico ;-p

En realidad, para un "conseguir", etc. Probablemente usaría un método estático (sin extensión).

Si solo quieres una forma de obtener el valor de una instancia de tipo anónimo (en un momento posterior), una lambda es probablemente la mejor opción. Ten en cuenta que necesitas algunos trucos para lograr esto:

static void Main() { var foo = new { name = "John", age = 25 }; var func = Get(foo, x => x.age); var bar = new { name = "Marc", age = 30 }; int age = func(bar); } // template here is just for type inference... static Func<TSource, TValue> Get<TSource, TValue>( TSource template, Func<TSource, TValue> lambda) { return lambda; }

(edita el comentario) Definitivamente hay este atributo:

var foo = new { A = "B" }; Type type = foo.GetType(); CompilerGeneratedAttribute attrib = (CompilerGeneratedAttribute) Attribute.GetCustomAttribute( type, typeof(CompilerGeneratedAttribute)); // non-null, therefore is compiler-generated