这就是我的功能:
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;
}
我有这个行星清单:private List<Planet> planetsList = new List<Planet>();
但是:我将使用其他列表,例如public List<Colony> ColonyList = new List<Colony>();
,这就是为什么我需要List<T>
和类Planet
:
class Planet
{
...
public string name { get; }
...
}
我尝试了这个:(some stuff) CheckUniqueName(name, planetsList)
在其他班级
据我所知,List<T>
并不了解.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;
}
这行不通,创建新列表的相同操作也行不通。
答案 0 :(得分:6)
您可以在此处使用一般约束:
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;
}
}
答案 1 :(得分:3)
另一种方法是传递一个委托,该委托知道如何从您传入的任何类型中获取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;
}
这样称呼它:
CheckUniqueName(planetsList, "name", planet => planet.name);
然后不必将您的name
属性称为name
-可以随心所欲地调用它。
为清楚起见,我编写了CheckUniqueName
方法的长版本,但您可以使用linq缩短它:
public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
return !items.Any(item => newName == nameSelector(item));
}
然而,走了这么远,您还可以完全废弃CheckUniqueName
方法,而只写:
!plantsList.Any(x => x.name == "name");