C# 匿名类型的编译器优化

C# 匿名类型的编译器优化,c#,.net-4.0,anonymous-types,compiler-optimization,C#,.net 4.0,Anonymous Types,Compiler Optimization,好吧,好吧,我知道这是一个黑客行为,但这是为了一个小小的数据处理项目,我想玩一玩 我一直认为编译器会检查C#程序中使用的所有匿名类型,如果属性相同,它只会在幕后创建一个类 假设我想用我拥有的一些类型化数据集创建一个匿名类型: var smallData1 = new smallData1().GetData().Select( x => new { Name = x.NAME, x.ADDRESS, City = x.CITY, State = x.STATE, Zip =

好吧,好吧,我知道这是一个黑客行为,但这是为了一个小小的数据处理项目,我想玩一玩

我一直认为编译器会检查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 });
我现在可以做一些有趣的事情,比如smallData2.Except(smallData1)等,一切正常

现在,如果我有一对更大的匿名类型:

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});
现在当我做bigData2时,除了(bigData1)编译器抱怨:

Instance argument: cannot convert from
'System.Data.EnumerableRowCollection<AnonymousType#1>' to
'System.Linq.IQueryable<AnonymousType#2>'
实例参数:无法从转换
“System.Data.EnumerablerRowCollection”到
“System.Linq.IQueryable”
为什么??太多属性,所以编译器认为不值得优化

谢谢

你试过了吗

bigData2.Except(bigData1.AsQueryable());
我刚刚运行了一个包含40个属性和20000000行的LINQ示例,没有遇到任何问题

(在LINQPad中尝试这个不幸不可折叠的示例)


是的。这不是房地产的数量。您有多确定适配器返回的数据类型完全相同?

与任何类型一样,匿名类型的作用域是其包含的程序集。只有当两个适配器位于同一个dll(实际上是模块IIRC)中时,编译器才能将其视为相等

除此之外,我会检查类型

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 );
        }
    }
}
静态类型标识(IEnumerable){return typeof(T);}
...
var t1=识别(bigData1),t2=识别(bigData2);
如果(t1==t2){
Console.WriteLine(“它们是一样的”);
}否则{
var props1=t1.GetProperties(),props2=t2.GetProperties();
if(props1.Length!=props2.Length){
控制台写入线(props1.Length+“vs”+props2.Length);
}否则{
Sort(props1,p=>p.Name);
Sort(props2,p=>p.Name);
for(int i=0;i
我想问题在于,AnonymousType#1无法转换为AnonymousType#2。。。问题是,为什么它们一开始是两种不同的类型?是的,适配器返回的数据类型略有不同,但区别只是类型化数据集的类型(它们来自不同的数据库)。所有的属性都是字符串,这就是为什么我认为我应该使用一个匿名类型,这样我就可以将数据视为一种类型而不是两种类型。OMG这两种类型从何而来。犯错误好吧,你完全正确。其中一种确实不同。我猜当你在深夜编写代码时就会发生这种情况:-O
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 );
        }
    }
}