2013-01-11 12 views
8

Mam niektóre zapytania dodatkowe, które są typu danych var. Pracują nad tabelą danych. Chciałbym przekazać je do innej metody, jak mogę to zrobić? Ex:Przekazywanie typu "var" do metody w C#

var subquery1= from results in table.AsEnumerable() 
       where //some condition 
       select new 
       { 
        column1=results.field1, 
        column2 = results.field2 
        etc., 
       } 
    var subquery2= from results in table.AsEnumerable() 
       where //different condition 
       select new 
       { 
        column1=results.field1, 
        column2 = results.field2 
        etc., 
       } 

Teraz chciałbym zdefiniować jakiś sposób przekazać te subquery1, subquery2 jako zmienne. ex:

void updategrid(var queries) 
      { 
      //some logic 
      } 

i wykonać metodę:

updategrid(subquery1); 
updategrid(subquery2); 

Kiedy próbuję użyć var ​​w sposobie definiowania to nie podoba to. Pomóż mi, jak to zrobić. Dzięki.

Odpowiedz

29

Twój wynik to sekwencja anonimowych obiektów. var Słowo kluczowe mówi po prostu do kompilatora "Hej, dedukuj argumenty dla mnie z użycia". Proces dedukcji typów z użycia nazywa się Type Inference. Ale nie można powiedzieć kompilatorowi C#, aby wyprowadzić typy argumentów metody w deklaracji metody. Ponadto w przypadku anonymous objects nie możesz podać ich nazwy. Więc nie powinieneś przekazywać ich na zewnątrz i wewnątrz innych metod. Możesz rzucić je do dynamic, a następnie uzyskać dostęp do ich członków poprzez CallSite (kompilator tworzy je, gdy uzyskujesz dostęp do obiektu dynamicznego, takiego jak myDynamic.Name) lub możesz rzucić anonimowy obiekt na object i uzyskać dostęp do jego właściwości poprzez odbicie, ale wszystkie te metody nie są C# idiomatyczny i naprawdę brakuje punktu anonimowych obiektów. Zamiast tworzenia anonimowych obiektów w zapytaniu

select new 
{ 
    //members selection 
} 

Tworzenie niestandardowego typu

public class Result 
{ 
    //Members declaration 
} 

I oznacz ją jako wynik zapytania jak w następnym przykładzie: (można zastąpić var słowa kluczowego zamiast IEnumerable<Result> - skompilowany Kod będzie taka sama)

IEnumerable<Result> subquery1 = from results in table.AsEnumerable() 
           where //some condition 
           select new Result 
           { 
            //fill members here 
           } 

Metoda będzie wyglądać

void updategrid(IEnumerable<Result> queries) 
{ 
    //some logic here with strongly typed sequence 
} 

Wtedy nazywamy updategrid jak po prostu updategrid(subquery1) i trzeba będzie całe piękno statycznie wpisanej sekwencji swoich elementów w ciele updategrid

+0

Dzięki za natychmiastową odpowiedź. Podążyłem za twoim podejściem i stworzyłem publiczną klasę, jak wyżej. Ale w zapytaniu LINQ pojawia się błąd informujący, że "członek jest niedostępny z powodu jego poziomu ochrony.(jest to błąd polegający na tym, że dokładnie // to członkowie wypełnieni tutaj) – svs

+0

sprawiają, że klasa 'public' i jej właściwości' public' –

+0

zadziałały. Dzięki. – svs

9

Var nie jest typem danych. Krótko mówiąc, "dowiedzieć się, jaki typ danych faktycznie jest, gdy kompilujesz aplikację". Możesz dowiedzieć się, jaki typ danych faktycznie jest i użyć go dla swojego parametru lub możesz utworzyć ogólną funkcję, która będzie działać z dowolnym typem danych.

0

Pewnie przydałby się dynamic odniesienia, ale nie będę idź na to.

Zamiast tego, lepszym rozwiązaniem jest tworzenie klas rzeczywistych dla tych typów danych i przekazywanie ich do metod.

Na przykład:

public class MyColumns 
{ 
    public string column1 {get;set;} 
    public string column1 {get;set;} 
    //etc. 
} 

którym można tworzyć tak:

var subquery1= from results in table.AsEnumerable() 
       where //some condition 
       select new MyColumns 
       { 
        column1=results.field1, 
        column2 = results.field2 
        //etc. 
       }; 

i posiadają funkcję takiego:

public void updategrid(IEnumerable<MyColumns> queries) 
{ 
} 
8
void updategrid(var queries) 

nie jest ważny C#.

var to cukier syntaktyczny - zmienna ma typ, ale nie trzeba jej deklarować, jeśli kompilator może statycznie określić, co powinno być.

Za pomocą parametru kompilator nie ma wystarczających informacji, aby określić typ.

Podobnie, nie można zadeklarować zmienną var bez przypisania:

var something; 

Trzeba będzie zapewnić rodzaje subquery1, subquery2 a parametr do updategrid wszystkie są takie same.

2

W języku C# nie ma typu "var". "var" jest po prostu słowem kluczowym, które mówi kompilatorowi, aby "przeanalizował wszystko, co będzie potem, aby dowiedzieć się, jaki jest typ". Odbywa się to podczas kompilacji, a nie w czasie wykonywania.

Zmienne, o których mówisz, są w rzeczywistości pisane jako typy anonimowe, które kompilator automatycznie generuje podczas kompilacji. Takie typy, ponieważ nie mają nazwy, nie mogą być używane do deklarowania typów parametrów ani zwracanych wartości.

Powinieneś utworzyć jawne klasy dla tych danych lub w .Net4 lub późniejszym użyć typu ogólnego Tuple <>.

7

Można zadeklarować metodę z argumentem typu var. Ale można napisać tak:

static void updategrid(dynamic queries) 
{ 
} 

var oznacza take type from right-hand side and declare variable with this type from left-hand side i jest przetwarzany w czasie kompilacji. Jak widać przy użyciu var jako typ argumentu metody nie ma sensu.

3

Zastosowanie Object lub dynamic

void updategrid(object queries) 

void updategrid(dynamic queries) 

var -> typ statyczny, który jest określony przez prawej stronie wyrażenia. Nie może być używany jako parametr/typ zwrotu

object -> Klasa podstawowa dla wszystkich typów .NET.

dynamic -> Typ zostanie rozwiązany w czasie wykonywania. W związku z tym kontrole czasu kompilacji nie są wykonywane, a program intellisense nie jest dostępny. Ma również koszt wydajności.

+0

'Obiekt' nie będzie działać. Do czego go użyje? –

+0

Aby uzyskać dostęp do niestandardowych właściwości niedostępnych w pliku System.Object, wymagane jest rzutowanie na typ betonu. Ale tak anonimowy typ nie może zostać usunięty przy pomocy tylko obiektu. – Tilak

Powiązane problemy