接口与类之将类的实例赋予接口的变量

pyrtvu 2011-07-11 04:29:19
public IList<CategoryInfo> GetCategories()
{
IList<CategoryInfo> categories = new List<CategoryInfo>();
//Execute a query to read the categories
using(SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, SQL_SELECT_CATEGORIES, null)) {
while (rdr.Read()) {
CategoryInfo cat = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
categories.Add(cat);
}
}
return categories;
}
最近在看PetShop,这段代码是项目SqlserverDAL中Category.cs,是用于接口实现的类。
现在不明白,IList<CategoryInfo> categories = new List<CategoryInfo>();
这是什么意思,把一个实例new List<CategoryInfo>()赋予接口变量IList<CategoryInfo> categories,对这个接口变量应该
怎么理解,它还是一个集合吗?应该怎么用,最近发现类的实例赋予接口的变量用得非常普遍,真的不是太明白。
...全文
166 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
pyrtvu 2011-07-12
  • 打赏
  • 举报
回复
补充一下,我在C#高级编程第6版第108页,找到“把引用变量声明为接口引用的方式,这表示它可以指向实现这个接口的任何类的实例。但我们只能通过这些引用调用接口的方法--如果要调用由类执行的、不在接口中的方法,就需要把引用强制转换为合适的类型。接口引用完全可以看做是类引用--但接口引用的强大之处在于,它可以引用任何实现该接口的类。”
看完这一段,豁然开朗,希望对有同样疑问的人有帮助。
pyrtvu 2011-07-12
  • 打赏
  • 举报
回复
可能限于自己当前的水平,很难很好的理解,留着以后慢慢体会,谢谢大家热心的帮助。
  • 打赏
  • 举报
回复
再比如说说Linq那么丰富的方法,基本上都是针对IEnumerable<T>和IQueryable<T>类型的对象来设计的。而什么样的对象有这样的接口?太多了,甚至简单的数组
int[] arr;
也有这样的接口,所以Linq的应用范围很大。

这就是设计师的责任。它把一个很具体很具体的体系,放到尽可能很大的类型背景上,就可以让程序更加通用。而一般的开发人员就会在之后实现这个系统其中一部跟,以及使用这个系统其它部分时,借力更多。
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 pyrtvu 的回复:]

自己思维有点进入死胡同,不过有另一点不明白,此处函数的返回型为什么用IList<CategoryInfo>,而不用List<CategoryInfo>?
[/Quote]

往往是为了更“大”。

看一下List<T>的源代码中的定义:
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
{
.......


但是不仅仅是List<T>继承自IList<T>,还可以有其它很多实现方式。假设一个任务,在定义时就是需求按照IList<T>类型来提交,那么不管之后的开发人员怎么实现,只要实现了就行了。所以这是两个层次,你不能只从低层次去要求它。
pyrtvu 2011-07-11
  • 打赏
  • 举报
回复
自己思维有点进入死胡同,不过有另一点不明白,此处函数的返回型为什么用IList<CategoryInfo>,而不用List<CategoryInfo>?
cloudtian101 2011-07-11
  • 打赏
  • 举报
回复
把接口和类看成指针理解就简单了。如:
A a =new A();
a是指向一个类型为A的对象,如果B是A的父类,则:
B b =new A();
b也是指向A的指针。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 pyrtvu 的回复:]
我有个疑问是categories是个集合类,里面已经包含有实例项,那么把categories变成接口型,那里面的实例项还在不在,能不能用,怎么用?
[/Quote]
没有什么“里边、外边”的概念,也没有什么“变成接口型”的概念。简单的东西被你理解得异常机械化和麻烦。

categories就是一个变量,它引用一个对象。它在设计时声明引用的类型是A,那么编译器保证验证这个变量引用的对象也兼容于A(包括A的子类实例),这样就可以帮开发人员在编码时做一些检验。

比如说代码:
机器 x= new 发电机();
x.启动();
这里不是什么机器里边有一个发电机,也不是什么发电机里边有一个机器。变量x定义为机器,它就可以引用任何兼容于机器的对象。这里只有一个发电机对象实例,没有什么单独实例为机器的对象实例。我们说x引用机器对象,其实就是指这个发电机。这个发电机就是这个机器,没有什么“变成机器型”这种概念。
pyrtvu 2011-07-11
  • 打赏
  • 举报
回复
PetShop代码调用软多,整体上把握比较困难,很多人都说这玩样好,怎么也要啃下,主要是对接口的实现的不是太清楚,看完C#入门经典,没有编程经验。
我有个疑问是categories是个集合类,里面已经包含有实例项,那么把categories变成接口型,那里面的实例项还在不在,能不能用,怎么用?
cloudtian101 2011-07-11
  • 打赏
  • 举报
回复
IList<CategoryInfo> categories = new List<CategoryInfo>();
简单的说,IList是List的父类,父类是可以指代子类的。比如:
Parent p = new Son();
cloudtian101 2011-07-11
  • 打赏
  • 举报
回复
petshop过程性的代码太多,建议不要用来学习三层。
pyrtvu 2011-07-11
  • 打赏
  • 举报
回复
还是不明白
xuexiaodong2009 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 chopper7278 的回复:]

IList<CategoryInfo> categories = new List<CategoryInfo>();
创建一个基于接口IList<CategoryInfo>的对象的实例,这个接口是由List<T>实现的。功能只限于IList<T>接口规定的功能。
[/Quote]同意
快乐乔巴 2011-07-11
  • 打赏
  • 举报
回复
IList<CategoryInfo> categories = new List<CategoryInfo>();
创建一个基于接口IList<CategoryInfo>的对象的实例,这个接口是由List<T>实现的。功能只限于IList<T>接口规定的功能。

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧