在对象列表 <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 传递给它。
它不起作用,因为搜索参数应与列表的元素类型相同。在这种情况下 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
.
另请参阅:
在我的 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 传递给它。
它不起作用,因为搜索参数应与列表的元素类型相同。在这种情况下 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
.
另请参阅: