Почему эти два анонимных типа не совпадают? - PullRequest
1 голос
/ 05 марта 2019

Может кто-нибудь сказать мне, почему эти два анонимных типа не совпадают?

{Name = "<>f__AnonymousType0`6" FullName = "<>f__AnonymousType0`6[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}

{Name = "<>f__AnonymousType0#1`6" FullName = "<>f__AnonymousType0#1`6[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}

УТОЧНЕНИЕ: (Я не знаю, важно ли это, но у одного анонимного типа есть символ #. О, # 01)

У меня есть эти две части кода.В том же классе (сборка).Один возвращает один из указанных выше анонимных типов, а другой возвращает другой.Однако оба оценивают одно и то же выражение.

Я провел сравнение ниже (некоторые просто чтобы увидеть результат, хотя некоторые должны правильно возвращать false).Но они все возвращают ложные.(Возможно, я пропустил некоторые, которые я пробовал)

ms возвращает один из анонимных типов.resultOfSelect возвращает другой анонимный тип.

Примечание: methodArgumentStringContainedSelectStatement во втором фрагменте кода содержит то же выражение, что и строка.


'ms == resultOfSelect'

'ms.GetType () == resultOfSelect'

'ms.GetType (). Равно (resultOfSelect.GetType ())'

'ms.GetType () == resultOfSelect.GetType () '

и другие.Все False

resultOfSelect debugView:

{Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable <<> f__AnonymousType0 # 1>}

мс. DebugView:

{Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable <<> f__AnonymousType0>}

1-й оператор:

   ' var ms =     (instanceContainingSelectMethod as IQueryable<Emar>).Select( nextEmarClassInstanceFromPreviousSelectMany => new { Schedule = nextEmarClassInstanceFromPreviousSelectMany.BEmem.Category.Substring(0, 1), Category = "0" + nextEmarClassInstanceFromPreviousSelectMany.BEmem.Category.Substring(1), Description = "", Year = nextEmarClassInstanceFromPreviousSelectMany.Month.Year, Time = nextEmarClassInstanceFromPreviousSelectMany.Actual_Time, Units = ((nextEmarClassInstanceFromPreviousSelectMany.BEmem.PurchDate ?? nextEmarClassInstanceFromPreviousSelectMany.BEmem.InServiceDate).Value.Year == nextEmarClassInstanceFromPreviousSelectMany.Month.Year)
? (nextEmarClassInstanceFromPreviousSelectMany.BEmem.SoldDate != null)
    ? (nextEmarClassInstanceFromPreviousSelectMany.BEmem.SoldDate.Value.Year == nextEmarClassInstanceFromPreviousSelectMany.Month.Year)
        ? (((12d - ((double)((nextEmarClassInstanceFromPreviousSelectMany.BEmem.PurchDate != null)
            ? (System.DateTime?)nextEmarClassInstanceFromPreviousSelectMany.BEmem.PurchDate.Value
            : nextEmarClassInstanceFromPreviousSelectMany.BEmem.InServiceDate).Value.Month)) + 1d) - (12d - ((12d - ((double)nextEmarClassInstanceFromPreviousSelectMany.BEmem.SoldDate.Value.Month)) + 1d))) / 12d
        : ((12d - ((double)(nextEmarClassInstanceFromPreviousSelectMany.BEmem.PurchDate ?? nextEmarClassInstanceFromPreviousSelectMany.BEmem.InServiceDate).Value.Month)) + 1d) / 12d
    : ((12d - ((double)(nextEmarClassInstanceFromPreviousSelectMany.BEmem.PurchDate ?? nextEmarClassInstanceFromPreviousSelectMany.BEmem.InServiceDate).Value.Month)) + 1d) / 12d
: (nextEmarClassInstanceFromPreviousSelectMany.BEmem.SoldDate != null)
    ? (nextEmarClassInstanceFromPreviousSelectMany.BEmem.SoldDate.Value.Year == nextEmarClassInstanceFromPreviousSelectMany.Month.Year)
        ? (12d - ((12d - ((double)nextEmarClassInstanceFromPreviousSelectMany.BEmem.SoldDate.Value.Month)) + 1d)) / 12d
        : 1d
    : 1d } );'

2-й оператор:

            'Func<IQueryable<Emar>, object> customSelectManyDelegate =

           await CSharpScript
             .EvaluateAsync<Func<IQueryable<Emar>, object>>(methodArgumentStringContainingSelectStatement, options);

         resultOfSelect =  customSelectManyDelegate(instanceContainingSelectMethod as IQueryable<Emar>);'

1 Ответ

7 голосов
/ 05 марта 2019

Анонимные типы на самом деле предназначены только для использования в контексте одного метода, или может быть в некоторых сценариях отражения, где важна только форма, а не тип.

Так: спрашивать, почему тип отличается уже нарушает намерение языковой функции .Что касается , почему они разные: возможно, разные сборки или модули.Это относится, в частности, к веб-проектам, где представления компилируются позже основного кода.

Но: в принципе, не полагайтесь на это равенство.Это не гарантировано.Если вам небезразлично, что это за тип (и чему он равен), то ваши варианты включают:

  • объявление собственного формального типа и его использование - лучший вариант
  • использование значений-кортежей (ValueTuple<...>, но с поддержкой первоклассного языка, включая псевдо-имена, которые распространяются от вызываемого к вызывающему, но не от вызывающего к вызываемому)
  • с использованием кортежей (Tuple<...>)

Использование анонимных типов на самом деле не отображается в списке.

...