tag propiedades c# .net anonymous-types

tag - propiedades c# get set



¿Cómo puedo obtener el valor de una propiedad de un tipo anónimo? (12)

Tengo un datagrid rellenado por una consulta Linq. Cuando la fila enfocada en el datagrid cambia, necesito establecer una variable igual a una de las propiedades en ese objeto.

Lo intenté...

var selectedObject = view.GetRow(rowHandle); _selectedId = selectedObject.Id;

... pero el compilador no se preocupa por esto en absoluto ("La declaración incrustada no puede ser una declaración o una declaración etiquetada").

Parece que la propiedad debe ser de fácil acceso. La inspección del objeto durante el tiempo de ejecución muestra todas las propiedades que espero, simplemente no sé cómo acceder a ellas.

¿Cómo puedo acceder a la propiedad del objeto anónimo?

Editar para aclaraciones:

Resulta que estoy usando el control DevExpress XtraGrid. Cargué este control con una consulta Linq que estaba compuesta de varios objetos diferentes, por lo tanto, los datos no se ajustan realmente a ninguna clase que ya tenga (es decir, no puedo convertir esto en nada).

Estoy usando .NET 3.5.

Cuando veo los resultados del método view.GetRow (rowHandle) obtengo un tipo anónimo que se ve así:

{ ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }

Mi objetivo es obtener el ID de cliente de este tipo anónimo para poder hacer otras cosas (como cargar un formulario con ese registro de cliente).

Intenté un par de sugerencias en las primeras respuestas, pero no pude llegar a un punto en el que pudiera obtener este ID de cliente.


¿Alguna vez has tratado de usar la reflexión? Aquí hay un fragmento de código de ejemplo:

// use reflection to retrieve the values of the following anonymous type var obj = new { ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }; System.Type type = obj.GetType(); int clientid = (int)type.GetProperty("ClientId").GetValue(obj, null); string clientname = (string)type.GetProperty("ClientName").GetValue(obj, null); // use the retrieved values for whatever you want...


Como JaredPar adivinó correctamente, el tipo de retorno de GetRow() es object . Cuando trabaje con la cuadrícula DevExpress, podría extraer el valor deseado de esta manera:

int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId");

Este enfoque tiene inconvenientes similares a los de los "lanzamientos de tipo anónimo hacky" descritos anteriormente: se necesita una cadena mágica para identificar la columna más un tipo de conversión de objeto a int.


Cuando estaba trabajando para pasar tipos anónimos y tratar de volver a redactarlos, al final me resultó más fácil escribir un contenedor que manejara el trabajo con el objeto. Aquí hay un enlace a una entrada de blog al respecto.

http://somewebguy.wordpress.com/2009/05/29/anonymous-types-round-two/

En última instancia, su código se vería algo así.

//create an anonymous type var something = new { name = "Mark", age = 50 }; AnonymousType type = new AnonymousType(something); //then access values by their property name and type type.With((string name, int age) => { Console.Write("{0} :: {1}", name, age); }); //or just single values int value = type.Get<int>("age");


Devtrapress xtraGridView tiene un método como este GetRowCellDisplayText (int rowHandle, GridColumn column). Con este método, el siguiente código devuelve el ID del tipo anónimo.

var _selectedId = view.GetRowCellDisplayText(rowHandle, "Id");

Aunque esto no proporciona una respuesta a la pregunta "¿Cómo puedo obtener acceso a la propiedad del objeto anónimo?", Todavía intenta resolver la causa raíz del problema.

Intenté esto con la versión 11.1 de devXpress y puedo ver que la pregunta se formuló por primera vez hace casi 2.5 años. Posiblemente el autor de la pregunta podría haber encontrado una solución o haber encontrado la solución por sí mismo. Sin embargo, sigo respondiendo para que pueda ayudar a alguien.


Espero que esto ayude, estoy pasando una lista de interfaz, de la que necesito obtener una lista distinta. Primero obtengo una lista de tipo Anónimo y luego la camino para transferirla a mi lista de objetos.

private List<StockSymbolResult> GetDistinctSymbolList( List<ICommonFields> l ) { var DistinctList = ( from a in l orderby a.Symbol select new { a.Symbol, a.StockID } ).Distinct(); StockSymbolResult ssr; List<StockSymbolResult> rl = new List<StockSymbolResult>(); foreach ( var i in DistinctList ) { // Symbol is a string and StockID is an int. ssr = new StockSymbolResult( i.Symbol, i.StockID ); rl.Add( ssr ); } return rl; }


Esto puede ser incorrecto (es posible que no tenga suficiente código allí) pero ¿no necesita indexar en la fila para elegir la columna que desea? O si "Id" es la columna que desea, debería hacer algo como esto:

var selectedObject = view.GetRow(rowHandle); _selectedId = selectedObject["Id"];

Así es como agarraría el contenido de una columna en una red de datos. Ahora bien, si la columna en sí es un tipo anónimo, entonces no lo sé, pero si solo está obteniendo una columna con nombre con un tipo primitivo, esto debería funcionar.


Podría usar el tipo dinámico para acceder a las propiedades de los tipos anónimos en tiempo de ejecución sin utilizar la reflexión.

var aType = new { id = 1, name = "Hello World!" }; //... //... dynamic x = aType; Console.WriteLine(x.name); // Produces: Hello World!

Lea más sobre el tipo dinámico aquí: http://msdn.microsoft.com/en-us/library/dd264736.aspx


Puede recorrer las propiedades de un tipo anónimo como este:

var obj = new {someValue = "hello", otherValue = "world"}; foreach (var propertyInfo in obj.GetType().GetProperties() { var name = propertyInfo.Name; var value = propertyInfo.GetValue(obj, index: null); ... }


Si sabe lo que está haciendo y no teme que se produzcan errores en el tiempo de ejecución cuando cambia su código, podría convertir los datos de sus filas como dynamic :

var data = view.GetRow(rowHandle) as dynamic; int clientId = data.ClientID; string clientName = data.ClientName; int jobs = data.Jobs

Sin verificación en tiempo de compilación. Pero debería funcionar bien.


Una solución genérica para obtener el valor de un elemento de datos para una clave determinada

public static T GetValueFromAnonymousType<T>( object dataitem, string itemkey ) { System.Type type = dataitem.GetType(); T itemvalue = (T)type.GetProperty(itemkey).GetValue(dataitem, null); return itemvalue; }

Ejemplo:

var dataitem = /* Some value here */; bool ismember = TypeUtils.GetValueFromAnonymousType<bool>(dataitem, "IsMember");


Uno de los problemas con los tipos anónimos es que es difícil usarlos entre las funciones. No hay forma de "nombrar" un tipo anónimo y, por lo tanto, es muy difícil dividirlo entre ellos. Esto evita que se utilicen como expresión de tipo para cualquier cosa que aparezca en los metadatos y sea definida por el usuario.

No puedo decir exactamente qué API está utilizando arriba. Sin embargo, no es posible que la API devuelva un tipo anónimo fuertemente tipado, por lo que mi conjetura en que selectedObject se escribe para objetar. C # 3.0 y anteriores no admiten el acceso dinámico, por lo que no podrá acceder a la identificación de la propiedad, incluso si está disponible en tiempo de ejecución.

Necesitará uno de los siguientes para evitar esto.

  • Usa la reflexión para agarrar la propiedad.
  • Cree un tipo completo y utilícelo para rellenar el datagrid
  • Utilice uno de los muchos tipos de modelos anónimos hacky

EDITAR

Aquí hay una muestra de cómo hacer un tipo anónimo hackeado

public T AnonymousTypeCast<T>(object anonymous, T typeExpression) { return (T)anonymous; } ... object obj = GetSomeAnonymousType(); var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 });

La razón por la que es intrépido es que es muy fácil romper esto. Por ejemplo, en el método donde se creó originalmente el tipo anónimo. Si agrego otra propiedad al tipo allí, el código anterior se compilará pero fallará en el tiempo de ejecución.


var result = ((dynamic)DataGridView.Rows[rowNum].DataBoundItem).value;