Re: [问题] 制作泛型类别一问

楼主: Peruheru (还在想)   2014-11-14 10:40:53
※ 引述《neo5277 (I am an agent of chaos)》之铭言:
: 后来找到一个 dynamic 型别 基本上看叙述就是一个没有型的型别你丢给她啥
: 他就吃啥很好养。
: 所以改成
: public class mymath
: : {
: : private mymath(){}
: : public static dynamic abs(dynamic x)
: : {return x>=0 ? : -x;}
: : }
: 就你丢时么进去他就用啥什么 不过字串跟布林不行
只是来回应贴文中提到得dynamic和泛型
先说好我也很弱所以打脸轻一点(预防针之意)
举实例来说
最近很常用到dapper
用dapper查询数据库很方便
他有个特点就是会把传回来的资料转成物件
先假设我要查询的资料表结构以类别表达是这样
public class Book {
public string Name { get; set; }
public string Author { get; set; }
public decimal Price { get; set; }
}
sql语句是这样:
string sql = "select Name, Author, Price from Book";
可以有两种写法:
result = cn.Query<Book>(sql);

result = cn.Query(sql);
而传回的内容
第一种是 Book物件 (的集合)
第二种是 dynamic物件 (的集合)
先假设只取一笔,让
var data = result.FirstOrDefault();
如果你用第一种
要取出Name字段,只要打 data.Name就好
若试图存取不存在的 Publisher字段,打 data.Publisher VS就会报错
因为型别已经决定了,什么有什么没有很清楚,所以IDE可以帮你抓错误
如果你用第二种
取出Name字段一样是打 data.Name
但是这时如果你想取 Publisher,打data.Publisher,什么事情都不会发生
等到你一执行那边,才会出现错误讯息告诉你没有这个字段
用dynamic,什么该有什么没有都得自己掌握
完全执政,要负完全的责任(误)(不要拿这个战我XD)
上面提到的 Query<Book>()方法,就是一个泛型方法
你可以改成 Query<string>() ,也可以改成 Query<int>(),就看你想传什么回来
当然也可以传回来其实是int,但你用string去接
重点就是 Query 这个函式,并没有强迫你要用什么型别,而是留着等你呼叫时决定
他就是一个 Query<T>() 的型别,而 T 就是泛型要指定的型别
我个人的理解是
泛型 : 不把型别写死,由呼叫者决定呼叫时他该用什么型别
这样只需要一个函式,就可以供给不同传回型态的需求使用
因为只是延后决定,编译时就会抓到如变量名打错的错误
dynamic : 从头到尾都不决定型别,连呼叫者都不知道会跑出什么
可以一下文字一下又变量字,甚至突然变成物件
在编译阶段难以发现错误,有错都是实际跑了才知道
所以用dynamic要特别小心谨慎,如果没有特别要利用dynamic的特性的话
最好还是都写成固定的型别,比较不会出错
作者: neo5277 (I am an agent of chaos)   2014-11-14 20:09:00
感谢您~~我再来研究一下

Links booklink

Contact Us: admin [ a t ] ucptt.com