首页新闻找找看学习计划

C# 泛型如何将类作为参数传递

0
悬赏园豆:50 [已解决问题] 解决于 2017-09-01 17:29

是这样的

我有好几个定义好的类

class A

{

...

}

class B

{

...

}

...

 

然后现在用泛型List<T>

public get(int number){


if(number==1)
{
var _d = new List<A>();
}
else if(number==2) {
var _d = new List<B>();
} 

...

}

 

我觉得这样太糟糕了,我现在想知道怎么把A、B这些类作为参数像这样直接赋值

复制代码
var _classname ...


if(number==1)  _classname=A;

if(number==2)  _classname=B;


var _d=new List<_classname>();
var _d2=new Dbset<_classname>();
var _d3=new Dbset<_classname>();
复制代码

这样做得到吗,因为不这样的话,有好多List<T>,没办法都一个个去if重新写一遍啊

或者说要达到这样的目的要怎么做, 代码动态指定为我想要的类型为 List<可变的类变量>

而不是直接写死 List<A>

MayBreath的主页 MayBreath | 初学一级 | 园豆:83
提问于:2017-09-01 15:40
< >
分享
最佳答案
0

谢谢大家了。。

我这边自己使用基类和派生类和约束解决了这个问题 

具体是这样的:

class BaseClass{

 public int id { get; set; }

 public int stock{ get; set; }

}



 public class myClassA: BaseClass{ }

public class myClassB: BaseClass{ }

 

 

 

使用的时候是这样的

public string Getmystock(int number)

{

if(number==1) var _d=Get<myClassA>();
if(number==2) var _d=Get<myClassB>();

}





 public string Get<T>() where T :BaseClass
{

 Expression<Func<T, object>> showkey = (p => new { p.id, p.stock});

  ...一堆重复





}

 

MayBreath | 初学一级 |园豆:83 | 2017-09-01 17:28
其他回答(4)
0

没讲清楚.详细讲吧.

吴瑞祥 | 园豆:28731 (高人七级) | 2017-09-01 16:18

是这样的,有个方法是放到web接口上的,不能直接在web接口上能直接写泛型

我是想这样

http://localhost/api/get?number=1   调用的就是类型A

http://localhost/api/get?number=2   调用类型B

 

这是我写的

public void (int number)
{


if(number==1) //当等于1时就是用A 除了A类型之外都是重复的
{
var _d1=new Get1<A>();

var _d2=new Get2<A>();

var _d3=new Get3<A>();
...
}

if(number==2) //当等于2时就是用B 重复的内容
{
var _d1=new Get1<B>();

var _d2=new Get2<B>();

var _d3=new Get3<B>();
...
}

if(number==3) //当等于3时就是用C 重复的内容
{
var _d1=new Get1<C>();

var _d2=new Get2<C>();

var _d3=new Get3<C>();
...
}



}

 

现在我就是想,想把以下这一堆重复代码 弄成只出现一次的。。

var _d1=new Get1<A或B或C>();

var _d2=new Get2<A或B或C>();

var _d3=new Get3<A或B或C>();

 

 

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 17:03
0

public get<T>(int number)

收获园豆:15
blackheart | 园豆:1752 (小虾三级) | 2017-09-01 16:22

我的泛型都是用这样的方法

 

但是这个在函数那边就已经定死T的类型了,现在是要动态设置T的类型

public get<T>(int number) ..

{

if(number==1var abc= new List<T>(); //这里的T已经是使用函数就定死的了



}

 

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 16:26

@MayBreath: 为什么要用number区分,而不是get的时候直接传泛型的类型参数?

支持(0) 反对(0) blackheart | 园豆:1752 (小虾三级) | 2017-09-01 16:42

@Blackheart: 因为这个方法是放到web接口上的,难道要在web接口上能直接写泛型类型吗

我是想这样

http://localhost/api/get?number=1

然后调用的就是类型A的

http://localhost/api/get?number=2

就是调用类型B的

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 16:48
0

是这个意思吗?

public class A
{
}

public class B
{

}

public class Factory
{
    public List<T> Get<T>()
    {
        return new List<T>();
    }
}

 

 

var factory = new Factory();

factory.Get<A>();
收获园豆:20
写代码的小2B | 园豆:4346 (老鸟四级) | 2017-09-01 16:25

不是的。。我现在就是很多个

public List<T> Get1<T>()
    {
        return new List<T>();
    }

public List<T> Get2<T>()
    {
        return new List<T>();
    }

public List<T> Get3<T>()
    {
        return new List<T>();
    }

 

然后用的是这个方法

public void (int number)
{


if(number==1) //当等于1时就是用A
{
var _d1=new Get1<A>();

var _d2=new Get2<A>();

var _d3=new Get3<A>();
...
}

if(number==2) //当等于2时就是用B
{
var _d1=new Get1<B>();

var _d2=new Get2<B>();

var _d3=new Get3<B>();
...
}

if(number==3) //当等于3时就是用C
{
var _d1=new Get1<C>();

var _d2=new Get2<C>();

var _d3=new Get3<C>();
...
}



}

 

 

我想改成这样的 直接传入类 一次性赋值 不用再 1、2、3的判断

public void Set(class _class)//伪代码参数

{


//一次性指定类 后赋值

var _d1=new Get1<_class>();

var _d2=new Get2<_class>();

var _d3=new Get3<_class>();



}

 

 

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 16:43

@MayBreath: 

你肯定还有别的需求吧,

要不然public void Set<T>(),就好了,不需要一定把类型通过参数的形式传递。

另外传递类型也是可以的,在C#里面是Type类型。

支持(0) 反对(0) 写代码的小2B | 园豆:4346 (老鸟四级) | 2017-09-01 16:48

@写代码的小2B: 

是的。

 因为这个方法是放到web接口上的,难道是要在web接口上能直接写泛型类型吗

我是想这样

http://localhost/api/get?number=1

然后调用的就是类型A的

http://localhost/api/get?number=2

就是调用类型B的

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 16:49

@MayBreath: 

Web接口传递参数也只能是基础类型。int,string等。

支持(0) 反对(0) 写代码的小2B | 园豆:4346 (老鸟四级) | 2017-09-01 16:52

@MayBreath: 

Web接口传递参数也只能是基础类型。int,string等。

支持(0) 反对(0) 写代码的小2B | 园豆:4346 (老鸟四级) | 2017-09-01 16:52

@写代码的小2B: 是的,所以我才要自己写转化啊。。传入number=1就用A类型 这样的。。奈何我用

Type abc=A;

VS提示说List<abc> 这个abc不能是变量。。

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 16:54

@MayBreath: 

获取一个类型的代码是:var tmp = typeof(A);

我感觉你钻牛角尖了,因为无论如何都会有一个转化的过程。

给你提供一个思路,用一个字典Dictionary来维护key(int),value(type)。

根据你自己的需求来调整。

支持(0) 反对(0) 写代码的小2B | 园豆:4346 (老鸟四级) | 2017-09-01 16:59

@写代码的小2B: 是的。。我也觉得钻牛角尖了。。但是就是这个需求不会骗人

另外不管是var tmp = typeof(A); 还是用Dictionary 获取到的都是变量。。List<T>里面都不能指定变量的。。而我恰好就是想要用变量 。。

C#解决这个就是用 void get<T>(int number) where T : class 

在使用的方法的时候才指定T的类型,但是这个又不能在接口上用。。哎

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 17:10
0

你这个简单工厂用起来好别扭,如果只是为了能够通过标识拿到对应的玩意你抽象a,b提个接口,最后方法返回的就是IEnumerable,用的时候直接强转成你对应的对象就可以了。比如

IEnumerable<yourInterFaceT> Get<yourInterFaceT>(int magicNumber){

 if(magicNumber==1)

  return new List<A>();

 return new List<B>();

}

 

IEnumerable val=Get(1);

List<A> a=(List<A>)a;

List<B> b=(List<B>)a;

甚至直接返回object也成。

收获园豆:15
Daniel Cai | 园豆:10374 (专家六级) | 2017-09-01 17:01

唔。。确实是为了能够通过标识拿到对应的玩意没错的,但是问题是这玩意儿是个类,拿不到啊。。

我要return的不是new List<A>(); 而是A这个类型 不管返回type A,他都是变量,而变量是没办法用在泛型T上的。

C#解决这个就是用 void get<T>(int number) where T : class 

在使用的方法的时候才指定T的类型,T这个位置是不能用变量的。。我现在就是想当成变量用

之所以没办法指定T是因为我要用在WEB接口上,WEB接口是没办法用泛型的。。

 

看来我只能增加代码了。没办法简写了

 

 

支持(0) 反对(0) MayBreath | 园豆:83 (初学一级) | 2017-09-01 17:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册