2012-01-05 37 views
5

Trong đoạn mã đơn giản dưới đây,Khai báo một biến ngầm gõ bên trong phạm vi có điều kiện và sử dụng nó bên ngoài

if(city == "New York City") 
{ 
    var MyObject = from x in MyEFTable 
        where x.CostOfLiving == "VERY HIGH" 
        select x.*; 

} 
else 
{ 
    var MyObject = from x in MyEFTable 
        where x.CostOfLiving == "MODERATE" 
        select x.*; 

} 

    foreach (var item in MyObject) 
    { 
    Console.WriteLine("<item's details>"); 
    } 

Các MyObject biến là không thể truy cập bên ngoài khối có điều kiện. Làm thế nào tôi có thể lặp lại bên ngoài if..else?

+0

Tôi cho rằng bạn có thể khai báo biến bên ngoài của các khối. – ChaosPandion

+1

Tôi nhận được "Các biến cục bộ được nhập hoàn toàn phải được khởi tạo" – FMFF

+1

Với 'x. *' Bạn muốn xây dựng một kiểu ẩn danh, phải không? Nếu không, tại sao bạn nhấn mạnh vào đánh máy ngầm? – CodesInChaos

Trả lời

24

Hãy làm rõ câu hỏi khó hiểu của bạn. Vấn đề là bạn có hai biến cục bộ, mỗi biến có kiểu "không thể nói" giống nhau - một chuỗi kiểu ẩn danh.

tôi sẽ thay đổi mã cụ thể của bạn như thế này:

string cost = city == "NYC" ? "HIGH" : "MODERATE"; 
var query = from row in table 
      where row.Cost == cost 
      select new { row.Population, row.Elevation }; 

Tuy nhiên, nếu bạn vẫn cần phải duy trì cấu trúc của các mã như nó là dành cho một số lý do, bạn có thể làm điều đó như thế này:

static IEnumerable<T> SequenceByExample<T>(T t){ return null; } 
... 
var query = SequenceByExample(new { Population = 0, Elevation = 0.0 }); 
if (whatever) 
    query = ... 
else 
    query = ... 

Đây là biến thể về mẹo được gọi là "truyền theo ví dụ", trong đó bạn đưa ra ví dụ về loại ẩn danh cho một phương pháp chung.Phương thức kiểu suy luận sau đó tìm ra kiểu trả về là gì, và sử dụng nó như kiểu gõ địa phương ngầm. Khi chạy, nó không làm gì ngoài việc tạo ra một đối tượng vô dụng mà sau đó bị loại bỏ nhanh chóng.

+3

Đây là, không nghi ngờ gì, mẹo thông minh nhất mà tôi từng thấy cả năm. – Polynomial

0

bạn sẽ phải xác định các MyObject như một var trước tình trạng này:

var MyObject = from x in MyEFTable 
        where x.CostOfLiving == "SOMETHING THAT'LL RETURN NO ROWS" 
        select x.*; 

này sẽ chỉ định một schema vào biến MyObject.

Bây giờ bạn có thể tiến hành với điều kiện của bạn như:

if(city == "New York City") 
{ 
    MyObject = from x in MyEFTable 
        where x.CostOfLiving == "VERY HIGH" 
        select x.*; 

} 
else 
{ 
    MyObject = from x in MyEFTable 
        where x.CostOfLiving == "MODERATE" 
        select x.*; 

} 
+2

Truy vấn thêm là không cần thiết. Chỉ cần viết ra loại thực tế. – ChaosPandion

+0

@ChaosPandion Tôi giả định loại là ẩn danh. – CodesInChaos

+0

@ChaosPandion, bên phải của bạn. – DoomerDGR8

1
List<MyObject> list = null; 

if(city == "New York City")  
    list = (from x in MyEFTable where x.CostOfLiving == "VERY HIGH" 
        select x.*).ToList();  
else  
    list = (from x in MyEFTable where x.CostOfLiving == "MODERATE" 
        select x.*).ToList();   

foreach (var item in list) 
    Console.WriteLine("<item's details>");  
4

Nếu bạn đang sử dụng một loại được đặt tên, chỉ cần khai báo một biến với kiểu đó trước khi if, nhưng sau đó các câu hỏi sẽ là tầm thường .

Vì vậy, tôi giả định bạn đang chọn một loại ẩn danh, vì vậy bạn không thể khai báo một biến rõ ràng với loại đó.

Truyền theo ví dụ sẽ hoạt động tại đây. Nhưng điều đó không giống như một giải pháp tốt. Có lẽ tạo ra một loại tên là một ý tưởng tốt hơn.

var myObject =Enumerable.Empty<RowType>.Select(row=>select new {columnA, columnB, columnC}); 
if(city == "New York City") 
{ 
    myObject= from x in MyEFTable 
        where x.CostOfLiving == "VERY HIGH" 
        select select new {columnA, columnB, columnC}; 
} 
else 
{ 
    myObject = from x in MyEFTable 
        where x.CostOfLiving == "MODERATE" 
        select select new {columnA, columnB, columnC}; 
} 

Hoặc trong ví dụ cụ thể của bạn người ta có thể dự án chỉ sau khi có điều kiện:

IQueryable<RowType> partialQuery; 
if(city == "New York City") 
    partialQuery=MyEFTable.Where(x=>x.x.CostOfLiving == "VERY HIGH"); 
else 
    partialQuery=MyEFTable.Where(x=>x.x.CostOfLiving == "MODERATE"); 
var myObject=partialQuery.Select(x=>x.new {columnA, columnB, columnC}); 

Hoặc:

Expression<Predicate<RowType>> filter;//Note that this is an Expression, not just a delegate 
if(city == "New York City") 
    filter=x=>x.x.CostOfLiving == "VERY HIGH"; 
else 
    filter=x=>x.x.CostOfLiving == "MODERATE"; 
var myObject=MyEFTable.Where(filter).Select(x=>x.new {columnA, columnB, columnC}); 

Hoặc thậm chí chỉ:

string s; 
if(city == "New York City") 
    s="VERY HIGH"; 
else 
    s="MODERATE"; 
var myObject=MyEFTable.Where(x=>x.CostOfLiving == s).Select(x=>x.new {columnA, columnB, columnC}); 

Đó là một trong thích hợp phụ thuộc vào cách bạn simp lified câu hỏi của bạn.

1

Bạn sẽ cần phải khai báo biến ngoài phạm vi của câu lệnh if để sử dụng nó trong vòng lặp foreach.

Nếu biến được khai báo nhưng không được khởi tạo bên ngoài câu lệnh if thì nó không thể được gõ hoàn toàn vì trình biên dịch sẽ không có biểu thức để xác định loại.

Nếu nó chỉ được sử dụng trong vòng lặp foreach, bạn có thể khai báo nó dưới dạng IEnumerable.

2

thử điều này:

System.Linq.IQueryable<MyEFTable Object type> MyObject = null; 
if(city == "New York City") 
{ 
    MyObject = from x in MyEFTable 
      where x.CostOfLiving == "VERY HIGH" 
      select x.*; 
} 
else 
{ 
    MyObject = from x in MyEFTable 
      where x.CostOfLiving == "MODERATE" 
      select x.*; 
} 

foreach (var item in MyObject) 
{ 
    Console.WriteLine("<item's details>"); 
} 
3

Hãy thử điều này:

var ret = default(object); 
Các vấn đề liên quan