C#泛型方法,泛型约束问题

classProgram{staticvoidMain(string[]args){B[]bArray=A.CreateDataArray<B>(3);}classTem... class Program
{
static void Main(string[] args)
{
B[] bArray = A.CreateDataArray<B>(3);
}

class Template<T> where T : new()
{
public T obj;
public Template(T obj)
{
this.obj = obj;
}
}

class A
{
public static T[] CreateDataArray<T>(int length)
{
T[] dataArray = new T[length];
for (int i = 0; i < length; i++)
{
dataArray[i] = new T();
}
return dataArray;
}
}

class B
{
DateTime time;
string str;
public B()
{
this.time = DateTime.Now;
this.str = time.ToString();
}
}
}
A类中dataArray[i] = new T();这句编译出错:变量类型没有new()约束,因此无法创建该类的实例,怎么修改?
展开
 我来答
xiangjuan314
2016-01-05 · TA获得超过3.3万个赞
知道大有可为答主
回答量:2.9万
采纳率:0%
帮助的人:2909万
展开全部
泛型方法
在C#2.0中,方法可以定义特定于其执行范围的泛型参数,如下所示:

public class MyClass<T>
{
//指定MyMethod方法用以执行类型为X的参数
public void MyMethod<X>(X x)
{
//
}

//此方法也可不指定方法参数
public void MyMethod<X>()
{
//
}
}

即使包含类不适用泛型参数,你也可以定义方法特定的泛型参数,如下所示:

public class MyClass
{
//指定MyMethod方法用以执行类型为X的参数
public void MyMethod<X>(X x)
{
//
}

//此方法也可不指定方法参数
public void MyMethod<X>()
{
//
}
}

注意:属性和索引器不能指定自己的泛型参数,它们只能使用所属类中定义的泛型参数进行操作。
在调用泛型方法的时候,你可以提供要在调用场所使用的类型,如下所示:
//调用泛型方法
MyClass myClass = new MyClass();
myClass.MyMethod<int>(3);
泛型推理:在调用泛型方法时,C#编译器足够聪明,基于传入的参数类型来推断出正确的类型,并且它允许完全省略类型规范,如下所示:
//泛型推理机制调用泛型方法
MyClass myClass = new MyClass();
myClass.MyMethod(3);
注意:泛型方法无法只根据返回值的类型推断出类型,代码如下:

public GenericMethodDemo()
{
MyClass myClass = new MyClass();
/****************************************************
无法从用法中推理出方法“GenericMethodDemo.MyClass.MyMethod<T>()”的类型参数。
请尝试显式指定类型参数。
***************************************************/
int number = myClass.MyMethod();
}

public class MyClass
{
public T MyMethod<T>()
{
//
}
}

泛型方法中泛型参数的约束,如下:

public class MyClass
{

public void MyMethod<X>(X x) where X:IComparable<X>
{
//
}
}

您无法为类级别的泛型参数提供方法级别的约束。类级别泛型参数的所有约束都必须在类作用范围中定义,代码如下所示

public class MyClass<T>
{

public void MyMethod<X>(X x,T t) where X:IComparable<X> where T:IComparer<T>
{
//
}
}

而下面的代码是正确的

public class MyClass<T> where T:IComparable<T>
{

public void MyMethod<X>(X x,T t) where X:IComparable<X>
{
//
}
}

泛型参数虚方法的重写:子类方法必须重新定义该方法特定的泛型参数,代码如下

public class MyBaseClass
{
public virtual void SomeMethod<T>(T t)
{
//
}
}
public class MyClass :MyBaseClass
{
public override void SomeMethod<X>(X x)
{

}
}

同时子类中的泛型方法不能重复基类泛型方法的约束,这一点和泛型类中的虚方法重写是有区别的,代码如下

public class MyBaseClass
{
public virtual void SomeMethod<T>(T t) where T:new()
{
//
}
}
public class MyClass :MyBaseClass
{
//正确写法
public override void SomeMethod<X>(X x)
{

}

////错误 重写和显式接口实现方法的约束是从基方法继承的,因此不能直接指定这些约束
//public override void SomeMethod<X>(X x) where X:new()
//{

//}
}

子类方法调用虚拟方法的基类实现:它必须指定要代替泛型基础方法类型所使用的类型实参。你可以自己显式的指定它,也可以依靠类型推理(如果可能的话)代码如下:

public class MyBaseClass
{
public virtual void SomeMethod<T>(T t) where T:new()
{
//
}
}
public class MyClass :MyBaseClass
{
//正确写法
public override void SomeMethod<X>(X x)
{
base.SomeMethod<X>(x);
base.SomeMethod(x);
}
}

泛型委托
在某个类中定义的委托可以使用该类的泛型参数,代码如下

public class MyClass<T>
{
public delegate void GenericDelegate(T t);
public void SomeMethod(T t)
{

}
}
public GenericMethodDemo()
{
MyClass<int> obj = new MyClass<int>();
MyClass<int>.GenericDelegate del;
del = new MyClass<int>.GenericDelegate(obj.SomeMethod);
del(3);
}

委托推理:C#2.0使你可以将方法引用的直接分配转变为委托变量。将上面的代码改造如下

public class MyClass<T>
{
public delegate void GenericDelegate(T t);
public void SomeMethod(T t)
{

}
}
public GenericMethodDemo()
{
MyClass<int> obj = new MyClass<int>();
MyClass<int>.GenericDelegate del;

//委托推理
del = obj.SomeMethod;
del(3);
}

泛型委托的约束:委托级别的约束只在声明委托变量和实例化委托时使用,类似于在类型和方法的作用范围中实施的其他任何约束。
泛型和反射
在Net2.0当中,扩展了反射以支持泛型参数。类型Type现在可以表示带有特定类型的实参(或绑定类型)或未指定类型的泛型(或称未绑定类型)。像C#1.1中那样,您可以通过使用typeof运算符或通过调用每个类型支持的GetType()来获得任何类型的Type。代码如下:
LinkedList<int> list = new LinkedList<int>();
Type type1 = typeof(LinkedList<int>);
Type type2 = list.GetType();
Response.Write(type1 == type2);
typeof和GetType()也可以对泛型参数进行操作,如下

public class MyClass<T>
{
public void SomeMethod(T t)
{
Type type = typeof(T);
HttpContext.Current.Response.Write(type==t.GetType());
}
}

typeof还可以对未绑定的泛型进行操作,代码如下

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Type unboundType = typeof(MyClass<>);
Response.Write(unboundType.ToString());
}
}

public class MyClass<T>
{
public void SomeMethod(T t)
{
Type type = typeof(T);
HttpContext.Current.Response.Write(type==t.GetType());
}
}

请注意"<>"的用法。要对带有多个类型参数的未绑定泛型类进行操作,请在"<>"中使用","
Type类中添加了新的方法和属性,用于提供有关该类型的泛型方面的反射信息,见MSDN。
lirimalu
推荐于2018-03-04 · 超过11用户采纳过TA的回答
知道答主
回答量:20
采纳率:100%
帮助的人:25.6万
展开全部
class Template<T> where T : new() 这里的 where T : new()不需要,
应该放在public static T[] CreateDataArray<T>(int length) where T : new() 这里
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友a5eb3e1
2013-11-09 · TA获得超过4448个赞
知道大有可为答主
回答量:3486
采纳率:60%
帮助的人:2657万
展开全部
public static T[] CreateDataArray<T>(int length)  where T : new()
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式