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 элемента.
Здравствуйте, 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.
Здравствуйте, 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.
почему если я делаю класс и туда запихну все свойства, то тогда возвращается 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;
}
получается для анонимных типов идет сравнение как для структур, а для классов сравнение ссылок?
Здравствуйте, busk, Вы писали:
B>почему если я делаю класс и туда запихну все свойства, то тогда возвращается 3 элемента?
Потому что твой класс ничего не говорит о том, как его сравнивать на равенство. Он не переопределяет Equals()/GetHashCode().
Пруф-ссылок не будет, это совсем базовые вещи, поэтому лучше начать с любого учебника по шарпу
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, busk, Вы писали:
B>>почему если я делаю класс и туда запихну все свойства, то тогда возвращается 3 элемента?
S>Потому что твой класс ничего не говорит о том, как его сравнивать на равенство. Он не переопределяет Equals()/GetHashCode(). S>Пруф-ссылок не будет, это совсем базовые вещи, поэтому лучше начать с любого учебника по шарпу
я не к тому это.
анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать. а по умолчанию у классов сравнение по ссылкам идет.
так вот почему тогда 3 разных объекта дают при union 2 объекта? то есть идет сравнение как для структур
Здравствуйте, busk, Вы писали:
B>я не к тому это. B>анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать.
Наплевать, как он сделан — классом или структурой. Он семантически — "запись", и равенство двух экземпляров проверяется структурно, по всем полям. Семейство Tuple сделано аналогично.
Здравствуйте, busk, Вы писали:
B>я не к тому это. B>анонимный тип — это тоже класс и он тоже ничего не гооврит как его сравнивать.
Говорит, но прозрачно для пользователя.
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 объекта? то есть идет сравнение как для структур
"Как для стуруктур" — эт не совсем корректно. "Сравнение по значению" тогда уж.
Здравствуйте, 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 дают разные значения для анонимного типа и тюпла в связи с этим
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, busk, Вы писали:
B>>и Если я сделаю не анонимные типы, а класс с полями, то тогда будет 3 элемента.
AVK>А если у класса с полями перекрыть Equals, в котором сделать сравнение по содержимому полей?
Здравствуйте, 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 вернут.
Здравствуйте, 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 importedvar 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();
}
Здравствуйте, 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>