2010-07-23 39 views
7

OK OK, tôi biết đây là một hack, nhưng điều này là cho một dự án thao tác dữ liệu nhỏ và tôi muốn chơi xung quanh. ;-)Tối ưu hóa trình biên dịch của các loại vô danh

Tôi luôn ấn tượng rằng trình biên dịch sẽ kiểm tra tất cả các loại ẩn danh được sử dụng trong chương trình C# và nếu thuộc tính giống nhau, nó sẽ chỉ tạo một lớp đằng sau hậu trường.

Vì vậy, chúng ta hãy nói rằng tôi muốn tạo ra một loại vô danh của một số bộ dữ liệu đánh máy mà tôi có:

var smallData1 = new smallData1().GetData().Select(
    x => new { Name = x.NAME, x.ADDRESS, City = x.CITY, State = x.STATE, 
    Zip = x.ZIP, Country = x.COUNTRY, ManagerName = x.MANAGER_NAME, 
    ManagerID = x.MANAGER_ID }); 

var smallData2 = new smallData2().GetData().Select(
    x => new { x.Name, x.ADDRESS, x.City, x.State, x.Zip, x.Country, 
    x.ManagerName,x.ManagerID }); 

tôi bây giờ có thể làm những điều thú vị như smallData2.Except (smallData1); v.v., và tất cả đều hoạt động.

Bây giờ, những gì nếu tôi có một cặp lớn hơn các loại vô danh:

var bigData1 = new BigAdapter1().GetData().Select(
    x => new { x.FirstName, x.LastName, x.Address, x.City, x.State, 
    x.Zip, x.Country, x.Phone, x.Email, x.Website, x.Custom1, x.Custom2, 
    x.Custom3, x.Custom4, x.Custom5, x.Custom6, x.Custom7, x.Custom8, x.Custom9, 
    x.Custom10, x.Custom11, x.Custom12, x.Custom13, x.Custom14, x.Custom15, 
    x.Custom16, x.Custom17, x.Custom18, x.Custom19, x.Custom20, x.Custom21, 
    x.Custom22, x.Custom23, x.Custom24, x.Custom25, x.Custom26, x.Custom27, 
    x.Custom28, x.Custom29}); 

var bigData2 = new BigAdapter2().GetData().Select(
    x => new { x.FirstName, x.LastName, x.Address, x.City, x.State, x.Zip, 
    x.Country, x.Phone, x.Email, x.Website, x.Custom1, x.Custom2, x.Custom3, 
    x.Custom4, x.Custom5, x.Custom6, x.Custom7, x.Custom8, x.Custom9, x.Custom10, 
    x.Custom11, x.Custom12, x.Custom13, x.Custom14, x.Custom15, x.Custom16, 
    x.Custom17, x.Custom18, x.Custom19, x.Custom20, x.Custom21, x.Custom22, 
    x.Custom23, x.Custom24, x.Custom25, x.Custom26, x.Custom27, 
    x.Custom28, x.Custom29}); 

Bây giờ khi tôi làm bigData2.Except (bigData1); trình biên dịch than phiền:

Instance argument: cannot convert from 
'System.Data.EnumerableRowCollection<AnonymousType#1>' to 
'System.Linq.IQueryable<AnonymousType#2>' 

Tại sao? Quá nhiều thuộc tính, vì vậy trình biên dịch quyết định nó không đáng để tối ưu hóa?

Cảm ơn!

Trả lời

2

Yep. Nó không phải là số lượng tài sản. Làm thế nào chắc chắn là bạn rằng bộ điều hợp của bạn đang trở về chính xác cùng một loại dữ liệu?

+0

Yup, các bộ điều hợp đang trả về các kiểu dữ liệu hơi khác nhau, nhưng sự khác biệt chỉ là loại tập dữ liệu được nhập (chúng đến từ các cơ sở dữ liệu khác nhau). Tất cả các thuộc tính là các chuỗi, đó là lý do tại sao tôi figured tôi chỉ cần sử dụng một loại vô danh và điều đó sẽ cho phép tôi xử lý dữ liệu như ONE loại loại thay vì hai. – Pandincus

+0

OMG Ở ĐÂU ĐÓ CÓ TỪ ĐẾN TỪ. Err ... được rồi, bạn đã hoàn toàn đúng. Một trong những loại thực sự khác nhau. Tôi đoán đó là những gì sẽ xảy ra khi bạn mã muộn vào ban đêm: -O – Pandincus

2

Các bạn đã thử

bigData2.Except(bigData1.AsQueryable()); 

Tôi vừa mới chạy một ví dụ LINQ với 40 tính đến 20.000.000 hàng và tôi không chạy vào một vấn đề.

(Hãy thử điều này tiếc là không dụ collapsible trong LINQPad)

void Main() 
{ 
Test t = new Test(); 
var a = Enumerable.Range(1,10000000).Select(i => new 
{ 
    t.T0, t.T1, t.T2, t.T3, t.T4, t.T5, t.T6, t.T7, t.T8, t.T9, 
    t.T10, t.T11, t.T12, t.T13, t.T14, t.T15, t.T16, t.T17, t.T18, t.T19, 
    t.T20, t.T21, t.T22, t.T23, t.T24, t.T25, t.T26, t.T27, t.T28, t.T29, 
    t.T30, t.T31, t.T32, t.T33, t.T34, t.T35, t.T36, t.T37, t.T38, t.T39, 
}); 

Test2 t2 = new Test2(); 
var b = Enumerable.Range(1,10000000).Select(i => new 
{ 
    t2.T0, t2.T1, t2.T2, t2.T3, t2.T4, t2.T5, t.T6, t2.T7, t2.T8, t2.T9, 
    t2.T10, t2.T11, t2.T12, t2.T13, t2.T14, t2.T15, t2.T16, t2.T17, t2.T18, t2.T19, 
    t2.T20, t2.T21, t2.T22, t2.T23, t2.T24, t2.T25, t2.T26, t2.T27, t2.T28, t2.T29, 
    t2.T30, t2.T31, t2.T32, t2.T33, t2.T34, t2.T35, t2.T36, t2.T37, t2.T38, t2.T39, 
}); 

a.Except(b).Dump(); 
} 

class Test 
{ 
public string T0 { get; set ;} 
public string T1 { get; set ;} 
public string T2 { get; set ;} 
public string T3 { get; set ;} 
public string T4 { get; set ;} 
public string T5 { get; set ;} 
public string T6 { get; set ;} 
public string T7 { get; set ;} 
public string T8 { get; set ;} 
public string T9 { get; set ;} 
public string T10 { get; set ;} 
public string T11 { get; set ;} 
public string T12 { get; set ;} 
public string T13 { get; set ;} 
public string T14 { get; set ;} 
public string T15 { get; set ;} 
public string T16 { get; set ;} 
public string T17 { get; set ;} 
public string T18 { get; set ;} 
public string T19 { get; set ;} 
public string T20 { get; set ;} 
public string T21 { get; set ;} 
public string T22 { get; set ;} 
public string T23 { get; set ;} 
public string T24 { get; set ;} 
public string T25 { get; set ;} 
public string T26 { get; set ;} 
public string T27 { get; set ;} 
public string T28 { get; set ;} 
public string T29 { get; set ;} 
public string T30 { get; set ;} 
public string T31 { get; set ;} 
public string T32 { get; set ;} 
public string T33 { get; set ;} 
public string T34 { get; set ;} 
public string T35 { get; set ;} 
public string T36 { get; set ;} 
public string T37 { get; set ;} 
public string T38 { get; set ;} 
public string T39 { get; set ;} 
} 

class Test2 
{ 
public string T0 { get; set ;} 
public string T1 { get; set ;} 
public string T2 { get; set ;} 
public string T3 { get; set ;} 
public string T4 { get; set ;} 
public string T5 { get; set ;} 
public string T6 { get; set ;} 
public string T7 { get; set ;} 
public string T8 { get; set ;} 
public string T9 { get; set ;} 
public string T10 { get; set ;} 
public string T11 { get; set ;} 
public string T12 { get; set ;} 
public string T13 { get; set ;} 
public string T14 { get; set ;} 
public string T15 { get; set ;} 
public string T16 { get; set ;} 
public string T17 { get; set ;} 
public string T18 { get; set ;} 
public string T19 { get; set ;} 
public string T20 { get; set ;} 
public string T21 { get; set ;} 
public string T22 { get; set ;} 
public string T23 { get; set ;} 
public string T24 { get; set ;} 
public string T25 { get; set ;} 
public string T26 { get; set ;} 
public string T27 { get; set ;} 
public string T28 { get; set ;} 
public string T29 { get; set ;} 
public string T30 { get; set ;} 
public string T31 { get; set ;} 
public string T32 { get; set ;} 
public string T33 { get; set ;} 
public string T34 { get; set ;} 
public string T35 { get; set ;} 
public string T36 { get; set ;} 
public string T37 { get; set ;} 
public string T38 { get; set ;} 
public string T39 { get; set ;} 
} 
+0

Tôi tưởng tượng vấn đề là AnonymousType # 1 không thể được đúc để AnonymousType # 2 ... câu hỏi là, tại sao họ hai loại khác nhau để bắt đầu với? –

1

Các loại ẩn danh, như bất kỳ loại nào, là được sắp xếp theo cụm chứa có chứa. Trình biên dịch chỉ có thể coi như bình đẳng nếu hai bộ điều hợp nằm trong cùng một dll (thực ra, mô-đun IIRC).

Ngoài ra, tôi sẽ kiểm tra các loại ...

static Type Identify<T>(IEnumerable<T>) {return typeof(T);} 
... 
var t1= Identify(bigData1), t2= Identify(bigData2); 
if(t1 == t2) { 
    Console.WriteLine("they're the same"); 
} else { 
    var props1 = t1.GetProperties(), props2 = t2.GetProperties(); 
    if(props1.Length != props2.Length) { 
     Console.WriteLine(props1.Length + " vs " + props2.Length); 
    } else { 
     Array.Sort(props1, p => p.Name); 
     Array.Sort(props2, p => p.Name); 
     for(int i = 0 ; i < props1.Length ; i++) { 
      if(props1[i].Name != props2[i].Name) 
       Console.WriteLine(props1[i].Name + " vs " + props2[i].Name); 
      if(props1[i].PropertyType != props2[i].PropertyType) 
       Console.WriteLine(props1[i].PropertyType + " vs " + props2[i].PropertyType); 
     } 
    } 
} 
Các vấn đề liên quan