2012-03-17 38 views
11

Mam metodę w następujący sposób:Get wartości od anonimowego typu

public void MyMethod(object obj){ 

    // implement 

} 

A ja nazywam to tak:

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

Więc jak mogę wdrożyć MyMethod() uzyskać wartość myparam?

Edit

Używam tego:

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

ale wzrost błędu:

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

również użyć przerwania i widzę d mają myparam właściwości String.

A czy jest jakiś sposób, aby sprawdzić dynamiczny typ, jeśli zawierają żadnego majątku takiego:

if(d.contain(myparam))? 

Edycja II

To jest mój główny kod:

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 
} 

i nazwij go jako:

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

i błąd jest:

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 

Edycja III

To mój AssemblyInfo definicji HtmlHelper:

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

ale wystąpił błąd jeszcze: 'object' does not contain a definition for 'area' używam różne zespoły ale jak to możliwe, kiedy używam breakpointa, widzę, że mój dynamiczny areaobject ma area nazwa właściwości, a także widzę wartość tego, ale błąd powiedzieć: 'object' does not contain a definition for 'area' Nie mogę wymyślić, jak to możliwe?

Edit

zmienić zespół i teraz dynamiczny typ jest wewnętrzny ale błąd pozostaje przed

+1

Typy anonimowe są ważne tylko w zakresie, w którym zostały utworzone. W takim przypadku nie będziesz mógł go użyć w MyMethod – Jon

+0

Dlaczego próbujesz to zrobić? To najprawdopodobniej zły pomysł. – svick

+0

Byłem tę samą odpowiedź z tego artykułu. https://stackoverflow.com/questions/5286695/how-do-i-get-data-from-an-anonymous-type-thats-been-converted-to-an-object/30462304#30462304 –

Odpowiedz

19

Użyj tego jeden:

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

Cóż, można użyć dynamicznej wpisywanie jeśli używasz C# 4:

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

Pyta, dlaczego nie używasz nazwanego typu. Typy anonimowe nie są tak zaprojektowane, aby można je było wymieniać między różnymi metodami takimi jak ten.

EDYCJA: Zwróć uwagę, że jeśli jest to inny zestaw niż oryginalny kod tworzący obiekt, musisz użyć [InternalsVisibleTo], ponieważ anonimowe typy są wewnętrzne.

+0

Dziękuję za odpowiedź, ale jest błąd, używam w ten sposób: 'dynamic d = obj; string param = d.myparam; 'ale wzrost błędu: 'object' nie zawiera definicji 'myparam' również używam breakpointa i widzę właściwość string 'myparam'. – Saeid

+0

Czy istnieje sposób sprawdzenia typu dynamicznego, jeśli zawiera jakąkolwiek właściwość podobną do tej: 'if (d.contain (myparam))'? – Saeid

+1

@Sideid, to powinno działać. Czy możesz opublikować pełny kod, który nie działa dla Ciebie? Aby sprawdzić, czy obiekt ma jakąś właściwość, należy użyć odbicia lub uchwycić wyjątek rzutów wiązania dynamicznego. – svick

6

Po pierwsze, jak powiedzieli inni: nie rób tego w pierwszej kolejności. Nie chodzi o to, w jaki sposób powinny być używane typy anonimowe.

Po drugie, jeśli masz na to ochotę, możesz to zrobić na kilka sposobów. Powolny i niebezpieczny sposób polega na używaniu dynamiki, jak mówili inni.

Szybki i niebezpieczny sposobem jest użycie „oddanych przez przykład.

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?

użyć refleksji Oczywiście, jeśli masz zamiar użyć odbicie następnie nie ma potrzeby korzystania dynamiczny pierwsze miejsce. użyć dynamiczny do Unikaj używania Reflection, więc jeśli masz zamiar używać Reflection każdym razie, równie dobrze można po prostu trzymać go używać.

brzmi jak Państwo próbuję zrobić coś, co jest trudne do zrobienia w języku C#. Oceniłbym, czy chcesz to robić, a jeśli tak, to czy język C# jest dla ciebie językiem. Dynamiczny język, taki jak IronPython, może lepiej pasować do Twojego zadania.

+0

Wystąpił błąd: ' [A] <> f__AnonymousType0'1 [System.String] cannotbecastto [B] <> f__AnonymousType0'1 [System.String] .Type A pochodzi z 'App_Web_c3frks2a, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null' in context'Default'at location 'C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Tymczasowe pliki ASP.NET \ root \ ~ .. \ App_Web_c3frks2a.dll'. Typ B pochodzi z 'Myproject, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null'in kontekstu' Default'at location 'C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Tymczasowe pliki ASP.NET \ root \ ~ .. \ assembly \ dl3 \ ~ .. \ MyProject.DLL' – Saeid

+2

@Sidid: przesyłanie według przykładów działa tylko w przypadku anonimowych typów, które znajdują się * w tym samym zespole *. Jeśli zadeklarujesz typ C w jednym zestawie, nie możesz go przekonwertować na inny typ, zwany także C, w innym złożeniu; typy anonimowe są w ten sam sposób. Anonimowe typy nie były przeznaczone do użycia w różnych zespołach; ** użyj typu nominalnego **, a nie anonimowego. –

1

wszyscy mówią „nie rób tego na pierwszym miejscu”, ale to jest dokładnie to, co robi asp.mvc! (Nie zrozum mnie źle Nie podoba mi się to samemu, ale jeśli piszesz niestandardowych pomocników html, chcesz je nazwać tak, jak nazywasz zwykłych pomocników html ...)

I możesz użyć bolusa .mvc, aby ułatwić sobie życie:

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

"ale tak jak i to też" nie jest tak naprawdę dobrym uzasadnieniem czegokolwiek, kiedykolwiek. – Servy

+4

Kiedy piszę funkcję pomocnika ASP.MVC, powinna ona, moim zdaniem, być zgodna ze standardami funkcji pomocnika ASP.MVC. I jeśli większość funkcji pomocniczych ASP.MVC akceptuje parametry jako typy anonimowe, to myślę, że powinienem to poprzeć. W przeciwnym razie to powoduje – Nadav

+0

Ponadto, jeśli piszę kod, który akceptuje parametry inne niż typy anonimowe, a następnie trzeba przekazać je do (na przykład) parametru additionalViewData dla Html.EditorFor() to muszę przekonwertować moje parametry do anonimowego. obiekt. Czy wiesz, jak przekonwertować słownik na anonimowy obiekt? – Nadav

Powiązane problemy