首页 新闻 搜索 专区 学院

一个C#泛型方法,public IList<object> SelectByNo(string no)要求这里的object既能是User也能是Profile

0
悬赏园豆:10 [已解决问题] 解决于 2014-01-05 16:12
Profile继承自User,请问大神门要如何实现?
Scott Lewis的主页 Scott Lewis | 初学一级 | 园豆:151
提问于:2014-01-05 12:20
< >
分享
最佳答案
0

public IList<T> SelectByNo<T>(string no) where T : User {}

收获园豆:10
Ninja_Lu | 菜鸟二级 |园豆:289 | 2014-01-05 12:44

public IList<User> SelectByNo(string no),我的意思是最后调用的时候可以这样:Ilist<Profile> profiles = SelectByNo(no);Ilist<Profile> is Ilist<User>.如何实现呀?

Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 14:17

@Scott Lewis: 还是没太明白你的意图,有没有完整的用例?

Ninja_Lu | 园豆:289 (菜鸟二级) | 2014-01-05 14:27

@Ninja_Lu: 意思是SelectByNo(no)既能返回Ilist<user>,也能返回Ilist<profile>

Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 14:59

@Scott Lewis: 如果必须是“既能返回IList<User>又能返回IList<Profile>”,那么你只能通过范型约束来做到这一点:

public IList<T> SelectByNo<T>(string no) where T : User {}

//usage:

IList<User> users = Bar.SelectByNo<User>("some no");

IList<Profile> profiles = Bar.SelectByNo<Profile>("some no");

 

如没有没指定范型约束就想让SelectByNo“智能”的返回IList<User>或IList<Profile>这样的具类是不可以的,最多也只能返回IList<User>这样级别的结构(即便是方法内返回了IList<Profile>)。

其实如果这样的需求成立,那么好的设计应该是设计两个接口,SelectUserByNo和SelectProfileByNo而不是通过范型来做类型的筛选,因为你一旦已经抽象出了User和Profile的继承结构,那么就不应该针对User和Profile来具体的处理,否则就违背了抽象设计的原则。

Ninja_Lu | 园豆:289 (菜鸟二级) | 2014-01-05 15:09

@Ninja_Lu: “好的设计应该是设计两个接口,SelectUserByNo和SelectProfileByNo而不是通过范型来做类型的筛选,因为你一旦已经抽象出了User和Profile的继承结构,那么就不应该针对User和Profile来具体的处理”什么意思,设计两个接口不就是针对user和profile具体处理的么?下面代码的SelectUserByUserNo联合查询的user和profile,你觉得我是分开写两个方法好还是写一个方法好?

/// <summary>
        /// 通过编号获得用户实例
        /// </summary>
        /// <param name="no">编号</param>
        /// <returns></returns>
        public IList<T> SelectByNo<T>(string no) where T : User
        {
            SecUtility.CheckParameter(ref no, true, true, true, 0, "no");
            return SqlMapper.QueryForList<T>("SelectUserByUserNo", no);
        }

Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 15:19

@Scott Lewis:

就我来看,SelectByNo方法应该只返回IList<User>结构,因为你已经做了抽象的处理:Profile < User,那么接下来的业务就是在User结构内,例如有User.DoSomeThing()方法,Profile里覆写这个方法,这才是继承结构的正确使用方式。如果,你既要对User结构进行具体的操作,又要对Profile结构进行具体的操作,那么这里的继承结构就是有问题的,也就是说逻辑上是没有层级关系的两个类。(这是从设计的角度看)

现在的问题是,你的需求是SelectByNo要既可以返回IList<User>又可以返回IList<Profile>,本质上就是在对继承层次的不同具类做分别的操作了,所以我前面说了,SelectByNo应该只返回IList<User>,统一的进行抽象编程。

那么我再猜测一下,User在数据库里是一张表,Profile是和User表共享主键(或有外键约束)的表。如果是这样的话,其实是一种包含的关系,即User包含0-1的Profile,不应该是继承的关系。如果这个猜测是错的话,就忽略这段话吧。:-P

Ninja_Lu | 园豆:289 (菜鸟二级) | 2014-01-05 15:32

@Ninja_Lu: 这个方法其实是写在Dao层的

Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 15:44

@Ninja_Lu:确实是包含的关系

Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 15:45

@Scott Lewis: 那也只能这样了,语言级别只能够用下面的方法了:

public IList<T> SelectByNo<T>(string no) where T : User {}

//usage:

IList<User> users = Bar.SelectByNo<User>("some no");

IList<Profile> profiles = Bar.SelectByNo<Profile>("some no");

或者更大胆的方式(想想都可怕):

public IList<dynamic> SelectByNo(string no) {}

设计级别改不了的话就无能为力了……

Ninja_Lu | 园豆:289 (菜鸟二级) | 2014-01-05 15:49

@Ninja_Lu: 是可以在user里加一条public profile profile{get;set;}的,但这样要用到级联查询或者自己去写个方法查询,我就想用一次性获得所有属性,才有了这样的需求。谢谢你了,泛型我是刚刚接触,以前都没有使用过。

Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 16:03
其他回答(1)
0

public class Profile :User

public IList<User> SelectByNo(string no) {

......

 

}

Angkor--:-- | 园豆:1086 (小虾三级) | 2014-01-05 13:08

public IList<User> SelectByNo(string no),我的意思是最后调用的时候可以这样:Ilist<Profile> profiles = SelectByNo(no);Ilist<Profile> is Ilist<User>.如何实现呀?

支持(0) 反对(0) Scott Lewis | 园豆:151 (初学一级) | 2014-01-05 14:18
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册