简体   繁体   English

C# 列表不同

[英]C# List Distinct

I have a this simple custom class for storing information:我有一个简单的自定义 class 用于存储信息:

private class ccDetails
{
    public string Raw;
    public string Head;
    public string Name;
    public string Path;
    public string Type;
}

With this I create a list using and then assign values to it from another operation.有了这个,我使用创建一个列表,然后从另一个操作中为其分配值。 Once the assigning of values is complete I want to sort this as a distinct list based on Path.一旦值的分配完成,我想将其排序为基于路径的不同列表。

I'm using this code:我正在使用这段代码:

public void main()
{
    List<ccDetailst> cclist;

   //ADD STUFF TO LIST ....
   cclist.Add(.....

   List<ccDetails> controlElements = ccList.GroupBy(x => x.Path).Select(x => x.First()).ToList();
}

I thought that this would do the trick but I get this error:我认为这可以解决问题,但我收到了这个错误:

System.InvalidCastException
  HResult=0x80004002
  Message=Conversion from string "Company/Name" to type 'Boolean' is not valid.
  Source=Microsoft.CSharp
  StackTrace:
   at Microsoft.VisualBasic.CompilerServices.Conversions.ToBoolean(String Value)
   at Pxxxx.frmPxxxx._Closure$__._Lambda$__7-0(ccDetails x) in C:\Users\...\frmPXXX.vb:line 73
   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
   at System.Linq.Enumerable.<DistinctIterator>d__64`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Pxxxx.frmPXXX.PopulateControls() in C:\Users\...\frmPXXX.vb:line 73
   at Pxxxx.frmPxxxx.Button1_Click_1(Object sender, EventArgs e) in C:\Users\...\frmPXXX.vb:line 244
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
FormatException: Input string was not in a correct format.
What am I doing wrong in the Linq expression?

Line 73 is the the Linq expression above.第 73 行是上面的 Linq 表达式。
I've run the following "minimal" code in LinqPad and it works fine.我在 LinqPad 中运行了以下“最小”代码,它工作正常。

void Main()
{

            List<ccDetails> cclist = new List<ccDetails>();

            for (int a = 0; a < 5; a++)
            {
                ccDetails cc = new ccDetails();
                cc.Path = $"Company/Name";
                cc.Head = "Head" + a;
                cc.Name = "Name" + a;
                cc.Type = "Type" + a;
                cc.Raw = "Raw" + a;
                
                cclist.Add(cc);
                
            }
            List<ccDetails> controlElements = cclist.GroupBy(x => x.Path).Select(x => x.First()).ToList();
            
controlElements.Dump();

}


private class ccDetails
 {
   public string Raw;
   public string Head;
   public string Name;
   public string Path;
   public string Type;
   }

For the life of me I just can't figure out where and why a Boolean conversion is being attempted.对于我的一生,我只是不知道在哪里以及为什么要尝试 Boolean 转换。 Nowhere in my code is there a Boolean variable or a cast to boolean.我的代码中没有一个 Boolean 变量或转换为 boolean。 Any help is much appreciated.任何帮助深表感谢。

I want to sort this as a distinct list based on Path.我想根据路径将其排序为不同的列表。

This code should do the trick:这段代码应该可以解决问题:

public class Program
{
    public void Main()
    {

        List<ccDetails> cclist = new List<ccDetails>();
        for (int a = 0; a < 10; a++)
        {
            ccDetails cc = new ccDetails();
            // if a is odd, then insert duplicated path for testing
            cc.Path = "Company/Name" + (a % 2 == 0 ? a.ToString() : "");
            cc.Head = "Head" + a;
            cc.Name = "Name" + a;
            cc.Type = "Type" + a;
            cc.Raw = "Raw" + a;
            cclist.Add(cc);
        }
        List<ccDetails> controlElements = cclist            
            .OrderBy(x => x.Path)
            .Distinct(new comparer())
            .ToList();
            

        foreach(var entry in controlElements)
        {
            Console.WriteLine(entry.Raw);
            Console.WriteLine(entry.Head);
            Console.WriteLine(entry.Name);
            Console.WriteLine(entry.Path);
            Console.WriteLine(entry.Type);
            Console.WriteLine("==========");
        }
    
    }
}

public class ccDetails
 {
   public string Raw;
   public string Head;
   public string Name;
   public string Path;
   public string Type;
}

public class comparer : IEqualityComparer<ccDetails>
{
    public int GetHashCode(ccDetails details)
    {
        return details.Path.GetHashCode();
    }   

    public bool Equals(ccDetails a , ccDetails b)
    {
        return a.Path.Equals(b.Path);
    }
}

And the output:和 output:

Raw1
Head1
Name1
Company/Name
Type1
==========
Raw0
Head0
Name0
Company/Name0
Type0
==========
Raw2
Head2
Name2
Company/Name2
Type2
==========
Raw4
Head4
Name4
Company/Name4
Type4
==========
Raw6
Head6
Name6
Company/Name6
Type6
==========
Raw8
Head8
Name8
Company/Name8
Type8
==========

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM