2011-08-01 12 views
5

Utilizo C# asp.net4.Emitir un tipo anónimo en Objeto y recuperar un campo

tengo un método para rellenar un repetidor con tipos anónimos (campos: Título, CategoryId), en el interior del repetidor también coloca una etiqueta:

 var parentCategories = from c in context.CmsCategories 
           where c.CategoryNodeLevel == 1 
           select new { c.Title, c.CategoryId }; 
     uxRepeter.DataSource = parentCategories; 
     uxRepeter.DataBind(); 

tengo que cambiar las propiedades del texto para cada etiqueta dentro de mi repetidor en repetidor Evento ItemDataBound

protected void uxRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e) 
    { 
     HyperLink link = (HyperLink)e.Item.FindControl("uxLabel"); 
     uxLabel.Text = // How to do here!!!!!!!! 
    } 

Así que necesito establecer las propiedades de label.text utilizando e.Item (o una mejor manera si los hay).

Mi problema No puedo CASTAR el e.Item (título de campo de tipo anónimo) y configurarlo como propiedad del texto para mi etiqueta.

Entiendo que el tipo anónimo solo se puede convertir a tipo de objeto, pero en mi caso mi tipo anónimo tiene campos TitleI y CategoryId.

Mi pregunta:

cómo lanzar y recuperar el campo con que me interesa? ¿Gracias por su tiempo en esto?

EDIT: algún error que recibirá:

Unable to cast object of type '<>f__AnonymousType0`2[System.String,System.Int32]' to type 'System.String'. 

Respuesta

10

Las Opciones José regalos son buenos, pero hay es una manera horrible que puede hacer esto. Es algo frágil, ya que depende de que especifique el tipo anónimo en exactamente de la misma manera en dos lugares. Aquí vamos:

public static T CastByExample<T>(object input, T example) 
{ 
    return (T) input; 
} 

continuación:

object item = ...; // However you get the value from the control 

// Specify the "example" using the same property names, types and order 
// as elsewhere. 
var cast = CastByExample(item, new { Title = default(string), 
            CategoryId = default(int) }); 
var result = cast.Title; 

EDIT: Además de arrugas - las dos expresiones de creación de tipo anónimas tienen que estar en el mismo conjunto (proyecto). Perdón por olvidar mencionar eso antes.

+0

Algo que me he estado preguntando: ¿es simplemente un detalle de implementación que dos tipos anónimos de la misma forma son compatibles con el tipo, o es parte de la especificación que deben ser compatibles? –

+0

Gracias a Jon por su código completo. – GibboK

+3

@Rex: es parte de la especificación. No tengo una referencia sobre mí, pero básicamente * dentro del mismo conjunto *, dos expresiones de construcción de tipo anónimo con los mismos nombres de propiedad y tipos en el mismo orden deben referirse al mismo tipo. –

4

No se puede convertir el tipo anónimo para nada porque literalmente tienen ningún tipo de echarlo a, como se ha señalado ya, básicamente.

Así que realmente tiene dos opciones.

  1. No eche a un tipo anónimo, sino más bien un tipo conocido que se genera sólo para el manejo de este escenario o
  2. asignar una variable dinámica al elemento y utilizar las propiedades dinámicas en lugar

ejemplo 1:

var parentCategories = from c in context.CmsCategories 
    where c.CategoryNodeLevel == 1 
    select new RepeaterViewModel { c.Title, c.CategoryId }; 

ejemplo 2: (también creo que eres la última línea que significaba para asignar el enlace var)

protected void uxRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    HyperLink link = (HyperLink)e.Item.FindControl("uxLabel"); 
    dynamic iCanUseTitleHere = e.Item; 
    link.Text = iCanUseTitleHere.Title; //no compilation issue here 
} 
+0

Gracias Joesph por su respuesta. ¿Alguna desventaja en su Ejemplo 2 en lugar de Ex 1? gracias por su tiempo en este – GibboK

+1

@GibboK Bueno, usted pierde su fuerte tipeo, por lo que cualquier desarrollador que esté tocando el controlador de eventos ya debe saber a qué se puede acceder en ese objeto. Yendo con el primer ejemplo, obtienes tu fuerte tipeo, y lo único que tienes que saber en tu controlador de eventos es a qué clase enviar e.Item into. Todo lo demás se conoce en tiempo de compilación. – Joseph

+0

gracias Joseph por su comentario sobre este – GibboK

4

En este caso, puede usar un dynamic. Creo que el código sería:

protected void uxRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    dynamic link = (dynamic)e.Item.FindControl("uxLabel"); 
    uxLabel.Text = link.Title; //since 'link' is a dynamic now, the compiler won't check for the Title property's existence, until runtime. 
} 
0

¿No puedes simplemente emitir a (typeof(new { Title = "", CategoryID = 0 }))?

Cuestiones relacionadas