2012-03-17 18 views
11

tengo un método como el siguiente:Obtener el valor de tipo anónimo

public void MyMethod(object obj){ 

    // implement 

} 

Y llamarlo así:

MyMethod(new { myparam= "waoww"}); 

Entonces, ¿cómo puedo aplicar para obtener el valor MyMethod() miparam?

Editar

Yo uso este:

dynamic d= obj; 
string param = d.myparam; 

pero el aumento de error:

'object' does not contain a definition for 'myparam' 

También uso punto de interrupción y ver el D tienen miparam propiedad de cadena.

Y ¿hay alguna manera de comprobar tipo dinámico a si contiene ninguna propiedad como esta:

if(d.contain(myparam))? 

Editar II

Este es mi código principal:

public static MvcHtmlString SecureActionLink(this HtmlHelper htmlHelper, 
     string linkText, string actionName, string controllerName, 
     object routeValues, object htmlAttributes) { 


    string areaName = 
     (string)htmlHelper.ViewContext.RouteData.DataTokens["area"]; 

     dynamic areaObject = routeValues; 

     if(areaObject != null && !string.IsNullOrEmpty(areaObject.area)) 
      areaName = areaObject.area; 

// more 
} 

y llámelo como:

<p>@Html.SecureActionLink("Secure Link between Areas", "Index", "Context", 
          new { area = "Settings" }, null)</p> 

y el error es:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a 
definition for 'area' 

Line 303: dynamic areaObject = routeValues; 
Line 304: 
Line 305: if(areaObject != null && !string.IsNullOrEmpty(areaObject.area)) 
Line 306:  areaName = areaObject.area; 
Line 307: 

Source File: D:\Projects\MyProject\HtmlHelpers\LinkExtensions.cs Line: 305 

Editar III

Ésta es mi AssemblyInfo de HtmlHelper definición:

[assembly: AssemblyTitle("MyProject.Presentation")] 
[assembly: InternalsVisibleTo("cpanel.MyProject.dev")] 

pero hay un error aún: 'object' does not contain a definition for 'area' que utilizan diferentes montajes pero ¿cómo es posible, cuando uso el punto de ruptura puedo ver que mi areaobject dinámico tiene area nombre de la propiedad y también puedo ver el valor de eso, pero el error dice: 'object' does not contain a definition for 'area' No puedo entender cómo puede ser posible?

Editar

cambio el montaje y el tipo ahora dinámico es interno pero el error sigue siendo como antes

+1

Los tipos anónimos solo son válidos en el ámbito donde los creas. En este caso, no podrá usarlo en MyMethod – Jon

+0

¿Por qué está tratando de hacer esto? Es muy probable que sea una mala idea. – svick

+0

Yo tenía la misma respuesta con este artículo. https://stackoverflow.com/questions/5286695/how-do-i-get-data-from-an-anonymous-type-thats-been-converted-to-an-object/30462304#30462304 –

Respuesta

19

Uso ésta:

string area = areaObject.GetType().GetProperty("area").GetValue(areaObject, null); 
16

Bueno, se podría utilizar tipado dinámico si está usando C# 4:

public void MyMethod(object obj) { 
    dynamic d = obj; 
    Console.WriteLine(d.myparam); 
} 

Sin embargo, me pregunta por qué no está usando un tipo con nombre. Los tipos anónimos no están diseñados para compartirse entre diferentes métodos como este.

EDITAR: Tenga en cuenta que si se trata de un ensamblaje diferente al código original que crea el objeto, necesitará usar [InternalsVisibleTo] ya que los tipos anónimos son internos.

+0

Gracias por la respuesta, pero hay un error, uso así: 'dynamic d = obj; string param = d.myparam; 'pero el error aumenta: 'object' no contiene una definición para 'myparam'; también uso breakpoint y veo que' d' tiene myparam string propiedad. – Saeid

+0

¿Y hay alguna manera de verificar el tipo dinámico para si contiene alguna propiedad como esta: 'if (d.contain (myparam))'? – Saeid

+1

@Saeid, esto podría funcionar. ¿Podría publicar el código completo que no funciona para usted? Para verificar si un objeto tiene alguna propiedad, necesitaría usar el reflejo o atrapar la excepción que arroja el enlace 'dinámico'. – svick

6

En primer lugar, como otros han dicho: no hagas esto en primer lugar. Así no se pretendía utilizar los tipos anónimos.

En segundo lugar, si está decidido a hacerlo, hay varias maneras de hacerlo. La forma lenta y peligrosa es usar dinámica, como han dicho otros.

La manera rápida y peligroso es el uso de "proyectada por ejemplo:.

static T CastByExample<T>(object obj, T example) 
{ 
    return (T)obj; 
} 
static void M(object obj) 
{ 
    var anon = CastByExample(obj, new { X = 0 }); 
    Console.WriteLine(anon.X); // 123 
} 
static void N() 
{ 
    M(new { X = 123 }); 
} 

is there any way to check dynamic type to if contain any property?

utilizar la reflexión Por supuesto, si usted va a utilizar la reflexión a continuación no hay necesidad de usar dinámico en el primer lugar. se utiliza dinámica para evitar el uso de Reflexión , lo que si se va a utilizar la reflexión de todos modos, puede ser que también acaba de seguir utilizándolo.

parece que una Estoy tratando de hacer algo que es difícil de hacer en C#. Volvería a evaluar si desea hacer eso, y si lo hace, si C# es el idioma para usted. Un lenguaje dinámico como IronPython podría ser una mejor opción para su tarea.

+0

Hay un error: ' [A] <> f__AnonymousType0'1 [System.String] no se puede emitir a [B] <> f__AnonymousType0'1 [System.String] .Type A se origina de 'App_Web_c3frks2a, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null' en el contexto'Default'at location 'C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Archivos temporales ASP.NET \ root \ ~ .. \ App_Web_c3frks2a.dll'. El tipo B se origina en 'Myproject, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' en el contexto 'Default' en la ubicación 'C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Archivos temporales ASP.NET \ root \ ~ .. \ assembly \ dl3 \ ~ .. \ MyProject.DLL' – Saeid

+2

@Saeid: Casting por ejemplo solo funciona en tipos anónimos que * están todos en el mismo ensamblado *. Si declara un tipo llamado C en un ensamblaje, no puede convertirlo a un tipo diferente también llamado C en un ensamblaje diferente; los tipos anónimos son de la misma manera. Los tipos anónimos no estaban destinados a ser utilizados en todas las asambleas; ** use un tipo nominal **, no un tipo anónimo. –

1

todo el mundo dice "no lo haga en el primer lugar", pero esto es exactamente lo que hace asp.mvc! (No me malinterprete, no me gusta, pero si escribe helpers html personalizados, quiere llamarlos de la forma en que llama a los helpers html normales ...)

Y puede usar asp .mvc para hacerte la vida más fácil:

public void MyMethod(object obj){ 
    var dic=new System.Web.Routing.RouteValueDictionary(obj); 
    string param=dic["myparam"] as string; 
} 
+0

"pero tal y cual también" no es realmente una buena justificación para nada, nunca. – Servy

+4

Cuando estoy escribiendo una función auxiliar ASP.MVC, en mi opinión, debería cumplir con los estándares de las funciones auxiliares ASP.MVC. Y si la mayoría de las funciones auxiliares ASP.MVC aceptan parámetros como tipos anónimos, entonces creo que debería apoyar eso. De lo contrario, causa – Nadav

+0

Además, si estoy escribiendo código que acepta parámetros que no sean anónimos y luego tengo que pasarlo (por ejemplo) al parámetro adicionalViewData para Html.EditorFor(), entonces tengo que convertir mis parámetros a un anónimo objeto. ¿Sabes cómo convertir un diccionario a un objeto anónimo? – Nadav

Cuestiones relacionadas