在对象列表 <T> 上使用 "IndexOf"

Using "IndexOf" on a List<T> of objects

在我的 Visual Studio2019 C# 控制台程序(名为 'codeTester')中,我有这个对象:

        public class ipData
        {
            private string ip;
            private string region;
            private string country;

            public ipData(string ip, string region, string country)
            {
                this.ip = ip;
                this.region = region;
                this.country = country;
            }
                    
            public string Ip
            {
                get { return ip; }
                set { ip = value; }
            }

            public string Region
            {
                get { return region; }
                set { region = value; }
            }
            public string Country
            {
                get { return country; }
                set { country = value; }
            }
            
        }

我创建了这个对象的列表并添加了一些数据:

            List<ipData> ipInfo = new List<ipData>();
            ipInfo.Add(new ipData("192.168.0.199", "UT", "USA"));
            ipInfo.Add(new ipData("251.168.0.963", "NB", "CAN"));

现在我想在其中一个字段上搜索列表,所以我要求用户提供要搜索的数据:

            Console.WriteLine("Enter searh criteria: ");
            string searchparam = Console.ReadLine();

接下来我想要找到的项目的索引,如果有的话:

int x = ipInfo.IndexOf(searchparam);

但是这个语句抛出一个设计时异常,它说:

"参数 1:无法从 'string' 转换为 'codeTester.Program.ipData'"

所以我在这一点上停留了几个小时,我的所有搜索都没有产生任何相关的结果。我哪里错了?

那是因为 IndexOf 搜索列表中的确切对象。要让它工作,您必须将 ipData 传递给它。

为此,您应该使用 Find or FindIndex

它不起作用,因为搜索参数应与列表的元素类型相同。在这种情况下 ipData.

您可以使用 FindIndex which accepts a lambda expression 作为参数:

int x =
    ipInfo.FindIndex(ip => ip.Region == searchparam || ip.Country == searchparam);
if (x >= 0) {
    Console.WriteLine($"The IP address is {ipInfo[x]}");
} else {
    Console.WriteLine("not found");
}

或者您可以像这样使用 LINQ:

string ipAddress = ipInfo
    .FirstOrDefault(ip => ip.Region == searchparam || ip.Country == searchparam)?.Ip;

如果没有找到条目,这将 return 一个 null 字符串。

您也可以 return 整个记录:

ipData data = ipInfo
    .FirstOrDefault(ip => ip.Region == searchparam || ip.Country == searchparam);
if (data != null) {
    Console.WriteLine(
        $"Country = {data.Country}, Region = {data.Region}, IP = {data.ip}");
}

LINQ 还允许您 return 多个结果。例如。您可以 return 一个国家对应的所有数据,如下所示:

var result = ipInfo.Where(ip => ip.Country == "USA");
foreach (ipData data in result) {
    Console.WriteLine(
        $"Country = {data.Country}, Region = {data.Region}, IP = {data.ip}");
}

C# 命名约定规定 class 名称应以 PascalCase 书写。另一个约定是长度最多为两个字符的首字母缩略词全部大写 (IP)。根据这些约定,class 名称应为 IPData.

另请参阅: