C# 接口作为方法参数类型起作用,但不是接口列表
我有一个接口和两个继承该接口的类,如下所示C# 接口作为方法参数类型起作用,但不是接口列表,c#,interface,C#,Interface,我有一个接口和两个继承该接口的类,如下所示 public interface ILeader { int ID { set; get; } string Name { set; get; } } public class User : ILeader { public int ID { set; get; } public string Name { set; get; } } public class Group : ILeader { public i
public interface ILeader
{
int ID { set; get; }
string Name { set; get; }
}
public class User : ILeader
{
public int ID { set; get; }
public string Name { set; get; }
}
public class Group : ILeader
{
public int ID { set; get; }
public string Name { set; get; }
}
现在我有2个方法,它有一个类型为ILeader
的参数和一个类型为ILeader的IList
public void Change(ILeader leader)
{
//do some thing
}
public void ChangeList(IList<ILeader> leaderList)
{
//do some thing
}
错误是
cannot convert from List<User> to List<ILeader>
无法从一个列表转换到另一个列表
如何使我的
ChangeList
方法起作用,以便我可以传递用户列表和组列表?如果您使用的是.Net 4.0或更高版本,您可以将IList(T)更改为IEnumerable(T),它将起作用。IList(T)接口的T参数不是协变的,IEnumerable(T)接口的T参数是协变的。看
进一步解释。第二种方法实际上应该依赖泛型类型约束:
public void ChangeList<T>(IList<T> leaderList) where T : ILeader
{
//do some thing
}
public void变更列表(IList leaderList),其中T:ILeader
{
//做点什么
}
现在您可以传递这两个列表。在C#中,类不是共变的,这是您在这里尝试使用的特性。请参阅,以了解有关这方面的更多信息
需要记住的几个重要规则:
此功能仅适用于通用接口和委托。如果实现变量泛型接口,则实现类仍然是不变的。类和结构不支持C#4.0中的差异。
因此,以下内容无法编译:
// List<T> implements the covariant interface
// IEnumerable<out T>. But classes are invariant.
List<Person> list = new List<Employee>(); // Compiler error here.
//列表实现协变接口
//我数不清。但是类是不变的。
列表=新列表();//这里有编译器错误。
为了实现这一点,您需要将用户
强制转换为ILeader
。您可以使用userList.Cast()
执行此操作,因为IList
是不协变的,这意味着在用户列表中添加组
,这显然是无效的,更改列表
无法停止
要传递两种类型的列表,请将列表转换为列表
:
如果ChangeList
添加了除User
s以外的任何项目,则转换将失败。您的最佳选择是仅从结果中获取用户
s:
var leaderList = userList.Cast<ILeader>().ToList();
ChangeList(leaderList);
userList = leaderList.OfType<User>().ToList(); // will ignore anything that's not a `User`
var leaderList=userList.Cast().ToList();
变更列表(领导列表);
userList=leaderList.OfType().ToList();//将忽略任何不是“用户”的内容`
您可能无法执行,这取决于您想对变更列表执行的操作。ChangeList
的作用是什么?@DStanley:对列表项进行一些过滤,并为列表中的少数项重置Name属性可能与“谢谢”重复。如果我想从我的方法返回更新的列表,我是否应该使用IEnumerable作为返回类型,并将其转换回我调用此方法的任何位置的列表或列表?@Happy,IEnumerable是只读的,因此您不能使用此方法添加/删除项。但是,您可以修改项目本身(例如更改其名称属性)。因此,您不需要返回“结果列表”,因为原始列表没有更改。+1谢谢。我希望我的changelist方法对列表中某些用户的Name属性值进行更改并将其返回。我的返回类型应该是什么。从技术上讲,您不需要,因为列表只是对底层对象的引用,但是最好返回一个IList
,而不使用传入的列表。大多数“change”方法不会在传入的引用中更改,而是返回一个新实例。OK。因此,在调用该方法时,我应该使用作为列表强制转换它代码>?不,不能将其强制转换为列表-必须使用上面的方法进行转换
ChangeList(userList.Cast<ILeader>().ToList());
var leaderList = userList.Cast<ILeader>().ToList();
ChangeList(leaderList);
userList = leaderList.Cast<User>().ToList();
var leaderList = userList.Cast<ILeader>().ToList();
ChangeList(leaderList);
userList = leaderList.OfType<User>().ToList(); // will ignore anything that's not a `User`