C# 如何在函数中将对象列表作为参数传递,然后使用对象的属性C
这就是我的功能:C# 如何在函数中将对象列表作为参数传递,然后使用对象的属性C,c#,list,C#,List,这就是我的功能: public bool CheckUniqueName<T>(string newName, List<T> list) { for (int i = 0; i < list.Count(); i++) { if (list[i].name == newName) { return false; }
public bool CheckUniqueName<T>(string newName, List<T> list)
{
for (int i = 0; i < list.Count(); i++)
{
if (list[i].name == newName)
{
return false;
}
}
return true;
}
我试着这样做:在另一节课上检查一些东西
据我所知,List不知道.name属性
我尝试创建另一个列表并执行以下操作:
public bool CheckUniqueName<T>(string newName, List<T> list)
{
if (list is List<Planet>)
{
var newList = planetsList;
}
for (int i = 0; i < list.Count(); i++)
{
if (list[i].name == newName)
{
return false;
}
}
return true;
}
CheckUniqueName(planetsList, "name", planet => planet.name);
它不起作用,与创建新列表相同的事情也不起作用。您可以在此处使用通用约束:
public bool CheckUniqueName<T>(string newName, IEnumerable<T> items)
where T : INamed
=> !items.Any(i => (i.Name == newName));
public interface INamed
{
public Name { get; }
}
public class Planet : INamed
{
public Name { get; }
public Plant(string name)
{
Name = name;
}
}
public class Colony : INamed
{
public Name { get; }
public Colony(string name)
{
Name = name;
}
}
您可以在此处使用常规约束:
public bool CheckUniqueName<T>(string newName, IEnumerable<T> items)
where T : INamed
=> !items.Any(i => (i.Name == newName));
public interface INamed
{
public Name { get; }
}
public class Planet : INamed
{
public Name { get; }
public Plant(string name)
{
Name = name;
}
}
public class Colony : INamed
{
public Name { get; }
public Colony(string name)
{
Name = name;
}
}
另一种方法是传递一个委托,该委托知道如何从传入的任何类型中获取name属性:
public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
foreach (var item in items)
{
string name = nameSelector(item);
if (name == newName)
{
return false;
}
}
return true;
}
然后,您的name属性不必被称为name-它可以被称为任何您想要的
为了清晰起见,我编写了CheckUniqueName方法的长版本,但您可以使用linq缩短它:
public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
return !items.Any(item => newName == nameSelector(item));
}
另一种方法是传递一个委托,该委托知道如何从传入的任何类型中获取name属性:
public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
foreach (var item in items)
{
string name = nameSelector(item);
if (name == newName)
{
return false;
}
}
return true;
}
然后,您的name属性不必被称为name-它可以被称为任何您想要的
为了清晰起见,我编写了CheckUniqueName方法的长版本,但您可以使用linq缩短它:
public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
return !items.Any(item => newName == nameSelector(item));
}
您需要从一个基类派生,该基类具有每个派生类通用的Name属性,或者实现一个接口,该接口具有名称propertyNote,您的整个方法可以替换为!list.Anyx=>x.name==newname或list.Allx=>x.name!=新名字。考虑到这一点,我不确定是否有必要为此使用一个完全独立的方法,问题也就解决了……如果您使用不同类型的对象列表执行不同的操作,请编写不同的方法。这不是泛型的用途。泛型适用于您可以对T的不同类型执行相同操作的情况。在某些情况下,您可以使用泛型类型约束。但是编写这样一个方法的正确方法是使用一个具有所需属性的公共基类,然后编写一个采用IEnumerable的方法,而不是泛型方法。如上所述,您可能不需要编写任何方法,无论是泛型方法还是其他方法。非常感谢各位!那很有帮助!您需要从一个基类派生,该基类具有每个派生类通用的Name属性,或者实现一个接口,该接口具有名称propertyNote,您的整个方法可以替换为!list.Anyx=>x.name==newname或list.Allx=>x.name!=新名字。考虑到这一点,我不确定是否有必要为此使用一个完全独立的方法,问题也就解决了……如果您使用不同类型的对象列表执行不同的操作,请编写不同的方法。这不是泛型的用途。泛型适用于您可以对T的不同类型执行相同操作的情况。在某些情况下,您可以使用泛型类型约束。但是编写这样一个方法的正确方法是使用一个具有所需属性的公共基类,然后编写一个采用IEnumerable的方法,而不是泛型方法。如上所述,您可能不需要编写任何方法,无论是泛型方法还是其他方法。非常感谢各位!那很有帮助!这不需要使用泛型。它可以是CheckUniqueNamestring newName,IEnumerableitems@juharr只有当你能保证INamed的每个实现都是一个类而不是一个结构时,这才是真的。@juharr你说得对,我只是想按照OP的规范构建一个泛型方法,但他可能只需要一个通用接口,而不需要使用泛型。它可以是CheckUniqueNamestring newName,IEnumerableitems@juharr只有当你能保证INamed的每个实现都是一个类而不是一个结构时,这才是真的。@juharr你说得对,我只是想按照OP的规范构建一个通用方法,但也许他只是需要一个公共接口