Есть такой код простой.
Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.
Код рабочий
internal class Program
{
private static void Main(string[] args)
{
var dt1 = new dt()
{
id = 1,
ds = "20220101",
de = "20220202"
};
var dt2 = new dt()
{
id = 1,
ds = "20220101",
de = "20220202"
};
var l = new List<dt>();
l.Add(dt1);
l.Add(dt2);
//cnt = 2 ?
var s = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds.Concat(d.de)).Distinct().Count() });
//cnt = 1var s2 = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds + d.de).Distinct().Count() });
}
}
class dt
{
public int id;
public string ds;
public string de;
}
Для объединения строк можно также использовать оператор объединения строк языка, например + в C# и F#, или & и + в Visual Basic. Оба компилятора преобразуют оператор объединения в вызов одной из перегрузок String.Concat.
Здравствуйте, e.thrash, Вы писали:
ET>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.
Метод string.Concat статический, у тебя же в 1-м случае вызывается Enumerable.Concat<char>, соотв. Distinct делается для последовательности состоящей из 2-х разных IEnumerable-объектов — отсюда и 2.
Здравствуйте, e.thrash, Вы писали:
ET>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.
ET>
ET>internal class Program
ET>{
ET> private static void Main(string[] args)
ET> {
ET> var dt1 = new dt()
ET> {
ET> id = 1,
ET> ds = "20220101",
ET> de = "20220202"
ET> };
ET> var dt2 = new dt()
ET> {
ET> id = 1,
ET> ds = "20220101",
ET> de = "20220202"
ET> };
ET> var l = new List<dt>();
ET> l.Add(dt1);
ET> l.Add(dt2);
ET> //cnt = 2 ?
ET> var s = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds.Concat(d.de)).Distinct().Count() });
ET> //cnt = 1
ET> var s2 = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => d.ds + d.de).Distinct().Count() });
ET> }
ET>}
потому, что в первом случае Concat соединяет не строки, а энумераторы символов, получая новый энумератор. А два энумератора считаются различными объектами, даже если они на выходе дают одинаковый результат.
ET>тем более в мсдн написано такое
А это про другой Concat.
Слишком сложно пишете, от того и ошибки.
Попробуйте, например, изменить первый вариант на
var s = l.GroupBy(dt => dt.id).Select(b => new { Key = b.Key, cnt = b.Select(d => new string(d.ds.Concat(d.de).ToArray())).Distinct().Count()});
Здравствуйте, e.thrash, Вы писали:
ET>Есть такой код простой. ET>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.
var ds = "20220101";
var de = "20220202";
Console.WriteLine(ds + de);
Console.WriteLine(new String(ds.Concat(de).ToArray()));
Console.WriteLine(string.Concat(ds,de));
У вас Concat из linq вызывается. нужный Concat статик.
Здравствуйте, pilgrim_, Вы писали:
_>Здравствуйте, e.thrash, Вы писали:
ET>>Не пойму почему в случае Concat, Distinct по одинаковыми строкам возвращает 2 вместо 1.
_>Метод string.Concat статический, у тебя же в 1-м случае вызывается Enumerable.Concat<char>, соотв. Distinct делается для последовательности состоящей из 2-х разных IEnumerable-объектов — отсюда и 2.
да, не обратил внимание сначала. но тут вопросики.
когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?
ET>да, не обратил внимание сначала. но тут вопросики.
ET>когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?
Методы расширения позволяют "добавлять" методы в существующие типы без создания нового производного типа, перекомпиляции и иного изменения первоначального типа.
Методы расширения представляют собой разновидность статического метода, но вызываются так же, как методы экземпляра в расширенном типе.
Для клиентского кода, написанного на языках C#, F# и Visual Basic, нет видимого различия между вызовом метода расширения и вызовом методов, определенных в типе.
public static System.Collections.Generic.IEnumerable<TSource> Concat<TSource> (this
System.Collections.Generic.IEnumerable<TSource> first,
System.Collections.Generic.IEnumerable<TSource> second);
String.Concat статический, поэтому может быть вызван только через имя типа, а не имя экземпляра, в отличие от extension метода IEnumerable<Char>.Concat.
Здравствуйте, m2user, Вы писали:
ET>>да, не обратил внимание сначала. но тут вопросики.
ET>>когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?
M>Так работают extension методы.
это всё понятно. вопрос про то почему у меня string, а расширение вызывается для типа ienumerable<char> ?
Здравствуйте, e.thrash, Вы писали:
M>>Так работают extension методы.
ET>это всё понятно. вопрос про то почему у меня string, а расширение вызывается для типа ienumerable<char> ?
Здравствуйте, m2user, Вы писали:
ET>>да, не обратил внимание сначала. но тут вопросики.
ET>>когда делаешь над объектом string вызов метода ожидается что его обработает класс string или его предки. Как из string вывелся IEnumerable<char> ?
M>Так работают extension методы.
благими намерениями, отличный способ замусорить код. Самого корежит от обилия расширений в редакторе.