作者Peruheru (还在想)
看板C_Sharp
标题[问题] Callback未定型别时的处理方式
时间Wed Nov 25 14:50:26 2015
我希望某个类别里面有个函式
该函式的动作、输入、输出型态都由呼叫者决定
但实际执行的时机由该类别自己决定
类似撰写一个输出入型态都由自己决定的事件
而且该类别会成为集合,所以每个集合内的物件该函式的动作都不一样
不过不知道要怎麽写才是正确写法,还是说这件事无法做到?
参考
http://tinyurl.com/phkcmwp 的方法,但是他要求在类别上加上<Tin, Tout>
但这样一来我就不能用物件集合去处理它了,因为宣告变数时无法省略泛型型别
如果要维持物件集合的样子,就变成不能用泛型而要针对每个输出入型别各写一个作多载
这种做法感觉实在太没有弹性了不想这麽做阿orz
请问有没有比较好的方法,或是我什麽地方观念搞错了吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.134.18.8
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1448434229.A.1E3.html
※ 编辑: Peruheru (220.134.18.8), 11/25/2015 15:46:09
1F:→ m339606: 看不是很懂...你要的不就是泛型吗? 11/25 19:17
不只是泛型,还要委派,而且外部只能提供委派,实际执行是在内部,所以比较像事件
委派还做得到,但泛型要加上去就会限制类别的型别
我想做的事情举例来说
假设我是家具设计公司,然後我有一间跟我长期合作的木材加工厂
我手上有好多个案子在进行,每个案子都可能含有桌子、椅子、柜子等家具
今天第一个案子含五件家具,桌子一张,椅子两件,柜子两件
其中桌子,一件椅子和一件柜子都用我们设计好的现成外型去制作就好
但是有一件椅子和一件柜子客户有要求客制化,椅子要客制化图案,柜子要多隔一层
我送了五个设计图过去木材加工厂,其中有三件照设计图做就好
但有两件除了原本的设计图,还加上客制化说明调整部分的文件
然後我们公司等着收货就好,实际执行家具制造都是加工厂的事
委派就是客制化文件说明客制化内容和步骤
泛型就是客制化处理时需要的材料和成果
决定泛型会卡住就在於,如果我决定客制化文件泛型是为椅子而作而且输入枫木
那麽我那批家具(List)就只能全部都是用枫木做椅子 class 家具制造<枫木, 椅子>{}
因为宣告List限制该类别泛型对象要一致
var 第一批订单 = new List<家具制造<枫木, 椅子>>()
但我有可能会需要 家具制造<漂流木, 椅子> 或 家具制造<违法桧木, 鞋柜>
这样就无法作为List宣告了
经过网友来信讨论
目前是使用 public Func<T, object> 客制化{ get; set;} 来应对固定型别要求
然後用List<家具制造<第一批订单材料, object>>()来宣告
订单材料就包含枫木、漂流木、违法桧木的内容,依照每次订单不同而改变
输出就自己转型,将其定义写成enum作为另外一个属性来确定转型後是椅子还是柜子
虽然不是原本想像中的做法,至少目前可以运作
感谢网友帮忙
2F:→ pauliaia: Chain-of-responsibility pattern 是这个吗 11/26 01:41
3F:→ pauliaia: 这是把switch case 拆出来写的一种方法 基本上多类型别 11/26 01:41
4F:→ pauliaia: 简单的方法就是用if(物件判断)c sharp我也很菜 11/26 01:43
我查了一下这方法
这跟我想要的作法不太一样耶
因为他还是只能宣告几个固定的操作方式
或是变成每个呼叫端都要写很多方法作继承,比较不合我的需求
比较希望用简单的赋值方式让呼叫端操作
不过学到新方法了,原来还有这种做法,感谢提供讯息
※ 编辑: Peruheru (220.134.18.8), 11/26/2015 16:03:21
5F:推 m339606: Sorry..你的举例我看了三次还是不太明白 11/26 21:05
6F:→ m339606: 直觉是要用interface来处理 11/26 21:05
7F:→ bantime: 楼上..原PO的东西我有跟他要code来看..感觉上interface 11/26 21:57
8F:→ bantime: 还是不行..因为也没有很完整的叙述 不然也许设计上可以改 11/26 21:57
9F:→ bantime: 因为我比较好奇return出来的东西要做什麽,有没有可能 11/26 21:58
10F:→ bantime: 在callback里面处理这样 11/26 21:58
11F:→ Peruheru: 好吧我举例难懂 囧 11/26 22:19
我的类别是写给其他写程式的人使用的工具
但是使用者程度有高有低
没办法要求大家都要懂继承、介面的做法
委派是因为这个工具类别有部分资料需要特别处理过
像是有的地方需要拆解字串转换後才是实际可以继续处理的东西
有的地方则是需要将字串依照规则转为日期格式後继续处理
每个呼叫处都略有不同,没办法事先写好所有处理方式(而且还会再修改、增加)
介面和继承理论上可以达成类似效果,但是这会增加呼叫这个类别的难度
我写的类别除了委派要使用者自己决定以外,其他都是类别内自己完成并传送结果
我希望使用者只要知道"我丢物件阵列和描述资料进去後,没出错就是完成了"就好
而不要让使用的人需要做太多事才能完成
所以介面和继承对我来说是下选
因为这类别主要不是写给我用的,我得顾及其他人撰写时的难易度
将类别当成一个元件或控制项,给他资料给他事件然後看他表演就好
感觉上是最容易让使用者上手的做法
大概是这样
※ 编辑: Peruheru (114.36.227.162), 11/26/2015 22:44:57
12F:推 m339606: 不如你直接把你要想要的结果用Code表示(不用可编译) 11/26 22:49
13F:→ m339606: 或是用流程图的方式来说明... 11/26 22:50
※ 编辑: Peruheru (114.36.227.162), 11/26/2015 23:34:24
14F:推 Litfal: 如果要让使用者简单使用,为什麽不考虑用工厂隐藏介面建立 11/26 23:35
15F:→ Litfal: 细节? 11/26 23:35
16F:→ Peruheru: 我马上去恶补工厂模式... 11/26 23:44
17F:→ bantime: 我是觉得工厂模式也不会是你需要的@@ 11/27 00:06
18F:→ bantime: 不然就是我没想到适合的方式.. 11/27 00:06
19F:→ Peruheru: 如果我没搞错工厂模式的做法,他所隐藏的细节仍然是我希 12/01 10:55
20F:→ Peruheru: 望使用者可以自订的地方,如同前面提到我并不能针对细节 12/01 10:56
21F:→ Peruheru: 事先决定做法,因为每个呼叫者作法可能有细微不同处 12/01 10:56
22F:→ Peruheru: 所以我的类别应该无法适用工厂方法 12/01 10:57