c# – 为什么这个扩展方法适用于泛型但不适用于集合基类型?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 为什么这个扩展方法适用于泛型但不适用于集合基类型?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2322字,纯文字阅读大概需要4分钟。
内容图文
![c# – 为什么这个扩展方法适用于泛型但不适用于集合基类型?](/upload/InfoBanner/zyjiaocheng/796/b2e3dbb5732f4d30b48e705935174663.jpg)
在我的项目中,我有以下类结构:
public interface IUpdateableModel
{
ModelState State { get; set; }
void ResetState();
}
public abstract class UpdateableModel : IUpdateableModel
{
public ModelState State { get; set; }
public void ResetState()
{
//Perform reset logic
}
}
public class MyUpdateableClass : UpdateableModel
{
//Some properties.
}
现在我尝试添加一些扩展方法以用于IUpdateable集合:
public static class UpdateableModelExtensions
{
public static bool HasUnsavedChanges(this IList<IUpdateableModel> collection)
{
return collection.Any(x => x.State != ModelState.Unmodified);
}
public static void ResetItemStates<T>(this IList<T> collection) where T : IUpdateableModel
{
var itemsToRemove = collection.Where(x => x.State == ModelState.New).ToList();
foreach (var item in itemsToRemove)
{
collection.Remove(item);
}
var itemsToAdd = collection.Where(x => x.State == ModelState.Deleted).ToList();
foreach (var item in itemsToAdd)
{
item.State = ModelState.Unmodified;
}
var itemsToReset = collection.Where(x => x.State == ModelState.Modified).ToList();
foreach (var item in itemsToReset)
{
item.ResetState();
}
}
}
正如在List< MyUpdateableClass>上使用它时所写的那样.产生编译器错误,类型不匹配.
public class MyClass
{
public IList<MyUpdateableClass> Items {get; set;}
public void MyMethod()
{
if(Items.HasUnsavedChanges()) //Compiler error
{
//Do some stuff
}
}
}
编译器错误是:
'IList<MyUpdateableModel>' does not contain a definition for
'HasUnsavedChanges' and the best extension method overload
'UpdateableModelExtensions.HasUnsavedChanges(IList<IUpdateableModel>)'
requires a receiver of type 'IList<IUpdateableModel>'
如果将扩展方法更改为IList< UpdateableModel>,则会看到相同的结果.
但是,如果我改为使用泛型来实现它,它可以正常工作:
public static bool HasUnsavedChanged<T>(this IList<T> collection)
where T : IUpdateableModel
{
return collection.Any(x => x.State != ModelState.Unmodified);
}
此外,如果我将使用情况更改为Items.Cast< IUpdateableModel>().ToList(),则第一个版本可以正常工作.
那么,当具体版本没有时,允许通用版本工作的技术细节是什么?
解决方法:
这是因为IList内容比签名允许的更具体.这可能导致违反隐含合同.
IList< IUpdateableModel>的合同是否必须能够将IUpdateableModel的任何实现者添加到列表中.对于List< ImplementationOfUpdateableModel>而言,这是不可能的.因为您只能添加ImplementationOfUpdateableModel类型的对象.
通用版本有效,因为它允许该方法接受更具体的对象内容的IList.
内容总结
以上是互联网集市为您收集整理的c# – 为什么这个扩展方法适用于泛型但不适用于集合基类型?全部内容,希望文章能够帮你解决c# – 为什么这个扩展方法适用于泛型但不适用于集合基类型?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。