Анонимные типы
От: busk  
Дата: 07.03.17 06:28
Оценка:
Есть вот такой код простой


    class Program
    {
        static void Main(string[] args)
        {
            var list1 = new List<object>();
            var list2 = new List<object>();

            list1.Add(new { Age = 55, FirstName = "Petr", SureName = "ivanov", width = (int?)null });
            list1.Add(new { Age = 551, FirstName = "Petr", SureName = "ivanov2", width = (int?)null });
            list2.Add(new { Age = 55, FirstName = "Petr", SureName = "ivanov", width = (int?)null });
                       
            var names = list1.Select(a => a).Union(list2.Select(b => b));
            
            Console.ReadKey();
        }   
    }




почему names содержит 2 элемента, а не 3? Ведь разные ссылки у всех элементов?
и Если я сделаю не анонимные типы, а класс с полями, то тогда будет 3 элемента.
Отредактировано 07.03.2017 18:09 VladD2 . Предыдущая версия .
Re: Анонимные типы
От: Sinix  
Дата: 07.03.17 06:48
Оценка:
Здравствуйте, busk, Вы писали:

B>почему names содержит 2 элемента, а не 3?

Union()

The Concat<TSource> method differs from the Union<TSource> method
because the Concat<TSource> method returns all the elements in the input sequences including duplicates,
whereas Union<TSource> returns only unique values.

(c)
Re: Анонимные типы
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 07.03.17 06:58
Оценка:
Здравствуйте, busk, Вы писали:

B>и Если я сделаю не анонимные типы, а класс с полями, то тогда будет 3 элемента.


А если у класса с полями перекрыть Equals, в котором сделать сравнение по содержимому полей?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Анонимные типы
От: busk  
Дата: 07.03.17 07:20
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, busk, Вы писали:


B>>почему names содержит 2 элемента, а не 3?

S>Union()
S>

S>The Concat<TSource> method differs from the Union<TSource> method
S>because the Concat<TSource> method returns all the elements in the input sequences including duplicates,
S>whereas Union<TSource> returns only unique values.

S>(c)

почему если я делаю класс и туда запихну все свойства, то тогда возвращается 3 элемента?

 public class Name 
    {         
        public string SureName { get; set; }
        public string FirstName { get; set; }
        public int Age { get; set; }
        public int Weight { get; set; }
        public int? width;
    }


получается для анонимных типов идет сравнение как для структур, а для классов сравнение ссылок?
Re[3]: Анонимные типы
От: Sinix  
Дата: 07.03.17 07:27
Оценка:
Здравствуйте, busk, Вы писали:

B>почему если я делаю класс и туда запихну все свойства, то тогда возвращается 3 элемента?


Потому что твой класс ничего не говорит о том, как его сравнивать на равенство. Он не переопределяет Equals()/GetHashCode().
Пруф-ссылок не будет, это совсем базовые вещи, поэтому лучше начать с любого учебника по шарпу
Re[4]: Анонимные типы
От: busk  
Дата: 07.03.17 07:39
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, busk, Вы писали:


B>>почему если я делаю класс и туда запихну все свойства, то тогда возвращается 3 элемента?


S>Потому что твой класс ничего не говорит о том, как его сравнивать на равенство. Он не переопределяет Equals()/GetHashCode().

S>Пруф-ссылок не будет, это совсем базовые вещи, поэтому лучше начать с любого учебника по шарпу

я не к тому это.
анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать. а по умолчанию у классов сравнение по ссылкам идет.
так вот почему тогда 3 разных объекта дают при union 2 объекта? то есть идет сравнение как для структур
Re[5]: Анонимные типы
От: hardcase Пират http://nemerle.org
Дата: 07.03.17 07:42
Оценка: +1
Здравствуйте, busk, Вы писали:

B>я не к тому это.

B>анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать.

Наплевать, как он сделан — классом или структурой. Он семантически — "запись", и равенство двух экземпляров проверяется структурно, по всем полям. Семейство Tuple сделано аналогично.
/* иЗвиНите зА неРовнЫй поЧерК */
Отредактировано 07.03.2017 7:43 hardcase . Предыдущая версия .
Re[5]: Анонимные типы
От: Sinix  
Дата: 07.03.17 07:45
Оценка:
Здравствуйте, busk, Вы писали:

B>я не к тому это.

B>анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать.
Говорит, но прозрачно для пользователя.

https://msdn.microsoft.com/en-us/library/bb397696.aspx

Because the Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashCode methods of the properties, two instances of the same anonymous type are equal only if all their properties are equal.


Поскольку анонимные типы — это чисто compile-time-фича, то ответственность за корректную реализацию на себя берёт компилятор, а не платформа, вот и вся разница.

B>так вот почему тогда 3 разных объекта дают при union 2 объекта? то есть идет сравнение как для структур

"Как для стуруктур" — эт не совсем корректно. "Сравнение по значению" тогда уж.
Re[6]: Анонимные типы
От: busk  
Дата: 07.03.17 07:56
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, busk, Вы писали:


B>>я не к тому это.

B>>анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать.
S>Говорит, но прозрачно для пользователя.

S>https://msdn.microsoft.com/en-us/library/bb397696.aspx

S>

S>Because the Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashCode methods of the properties, two instances of the same anonymous type are equal only if all their properties are equal.


S>Поскольку анонимные типы — это чисто compile-time-фича, то ответственность за корректную реализацию на себя берёт компилятор, а не платформа, вот и вся разница.


не знал. Кстати интересные вещи открылись, что == и Equals дают разные значения для анонимного типа и тюпла в связи с этим
Re[2]: Анонимные типы
От: busk  
Дата: 07.03.17 07:57
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, busk, Вы писали:


B>>и Если я сделаю не анонимные типы, а класс с полями, то тогда будет 3 элемента.


AVK>А если у класса с полями перекрыть Equals, в котором сделать сравнение по содержимому полей?


Если Equals переопределить, то да, всё норм
Re[7]: Анонимные типы
От: Sinix  
Дата: 07.03.17 08:06
Оценка: 17 (2) :)
Здравствуйте, busk, Вы писали:

S>>Поскольку анонимные типы — это чисто compile-time-фича, то ответственность за корректную реализацию на себя берёт компилятор, а не платформа, вот и вся разница.

B>не знал. Кстати интересные вещи открылись, что == и Equals дают разные значения для анонимного типа и тюпла в связи с этим

Ага. Что называется: собери все варианты:
        static void Main(string[] args)
        {
            var a = new { A = "A", B = "B" };
            var a2 = new { A = "A", B = "B" };
            var b = (A: "A", B: "B");
            var b2 = (A: "A", B: "B");
            var c = Tuple.Create("A", "B");
            var c2 = Tuple.Create("A", "B");

            Console.WriteLine(a==a2); // ok
            Console.WriteLine(b==b2); // CS0019 Operator '==' cannot be applied ...
            Console.WriteLine(c==c2); // Resharper's: Possible unintended reference comparison; to get a value comparison, use 'Equals' method
    
            Console.WriteLine("Done.");
            Console.ReadLine();
        }


но это ненадолго. В c# 7.x операторы для ValueTuple вернут.
Отредактировано 07.03.2017 8:11 Sinix . Предыдущая версия . Еще …
Отредактировано 07.03.2017 8:11 Sinix . Предыдущая версия .
Re[8]: Анонимные типы
От: SHEMA  
Дата: 09.03.17 08:37
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Ага. Что называется: собери все варианты:

S>
S>        static void Main(string[] args)
S>        {
S>            var a = new { A = "A", B = "B" };
S>            var a2 = new { A = "A", B = "B" };
S>            var b = (A: "A", B: "B");
S>            var b2 = (A: "A", B: "B");
S>            var c = Tuple.Create("A", "B");
S>            var c2 = Tuple.Create("A", "B");

S>            Console.WriteLine(a==a2); // ok
S>            Console.WriteLine(b==b2); // CS0019 Operator '==' cannot be applied ...
S>            Console.WriteLine(c==c2); // Resharper's: Possible unintended reference comparison; to get a value comparison, use 'Equals' method
    
S>            Console.WriteLine("Done.");
S>            Console.ReadLine();
S>        }
S>


S>но это ненадолго. В c# 7.x операторы для ValueTuple вернут.


Visual Studio 2017, .Net framework 4.6.2:
        static void Main(string[] args)
        {
            var a = new { A = "A", B = "B" };
            var a2 = new { A = "A", B = "B" };
            //var b = (A: "A", B: "B"); - Error CS8179  Predefined type 'System.ValueTuple`2' is not defined or imported
            //var b2 = (A: "A", B: "B"); - Error CS8179  Predefined type 'System.ValueTuple`2' is not defined or imported

            var c = Tuple.Create("A", "B");
            var c2 = Tuple.Create("A", "B");

            Console.WriteLine(a == a2); // False
            //Console.WriteLine(b == b2);
            Console.WriteLine(c == c2); // False

            Console.WriteLine("Done.");
            Console.ReadLine();
        }
Re[9]: Анонимные типы
От: Jack128  
Дата: 09.03.17 08:42
Оценка:
Здравствуйте, SHEMA, Вы писали:

SHE>Visual Studio 2017, .Net framework 4.6.2:

SHE>
SHE>        static void Main(string[] args)
SHE>        {
SHE>            var a = new { A = "A", B = "B" };
SHE>            var a2 = new { A = "A", B = "B" };
SHE>            //var b = (A: "A", B: "B"); - Error CS8179  Predefined type 'System.ValueTuple`2' is not defined or imported
SHE>            //var b2 = (A: "A", B: "B"); - Error CS8179  Predefined type 'System.ValueTuple`2' is not defined or imported

SHE>            var c = Tuple.Create("A", "B");
SHE>            var c2 = Tuple.Create("A", "B");

SHE>            Console.WriteLine(a == a2); // False
SHE>            //Console.WriteLine(b == b2);
SHE>            Console.WriteLine(c == c2); // False

SHE>            Console.WriteLine("Done.");
SHE>            Console.ReadLine();
SHE>        }
SHE>


Install-Package System.ValueTuple
Re[9]: Анонимные типы
От: Sinix  
Дата: 09.03.17 18:27
Оценка:
Здравствуйте, SHEMA, Вы писали:

SHE>Visual Studio 2017, .Net framework 4.6.2:

  Как-то так
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.