Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何保证T是一个类?_C#_.net_Generics - Fatal编程技术网

C# 我如何保证T是一个类?

C# 我如何保证T是一个类?,c#,.net,generics,C#,.net,Generics,我有下一个代码: public static T GetSerializedCopy<T> (T src) { //some code to obtain a copy } publicstatict GetSerializedCopy(tsrc) { //获取副本的一些代码 } 如何保证T是一个类,而不是一个结构、枚举或其他类似的东西?公共静态T GetSerializedCopy(T src),其中T:class public static T GetSerialized

我有下一个代码:

public static T GetSerializedCopy<T> (T src)
{
  //some code to obtain a copy
}
publicstatict GetSerializedCopy(tsrc)
{
//获取副本的一些代码
}
如何保证T是一个类,而不是一个结构、枚举或其他类似的东西?

公共静态T GetSerializedCopy(T src),其中T:class
public static T GetSerializedCopy<T> (T src) where T : class

很容易确保

    public static T GetSerializedCopy<T>(T src) where T : class
    {
        //some code to obtain a copy
        return default(T);
    }
publicstatict GetSerializedCopy(tsrc),其中T:class
{
//获取副本的一些代码
返回默认值(T);
}
使用以下方法:

where T: class
是的

publicstatict GetSerializedCopy(tsrc)
T:在哪里上课
{
//获取副本的一些代码
}

您可以在接口上使用类型约束


认为将
where T:class
添加到泛型方法/类型声明中可以实现这一点是常见的错误(请参见此处的答案),但这是错误的。这实际上意味着“
T
必须是引用类型”,其中也包括委托和接口(加上数组,以及类似
string
的东西)

如果你想要一门课,有两种方法;最简单的方法是坚持使用
,其中T:class,new()
,因为接口和委托都不能有构造函数。但是,在拒绝没有公共无参数构造函数的类方面,这确实存在错误否定

唯一的其他方法是在运行时:

if(!typeof(T).IsClass) throw new InvalidOperationException("T must be a class");


同样,
其中T:struct
也不意味着“
T
必须是值类型”!它意味着“
T
必须是不可为空的值类型”;涉及
Nullable
的类型不满足
T:struct
,尽管事实上
Nullable
struct

实际上,这并不确保T是一个类;它确保它是一个reference@MarcGravell你真的认为这就是问题所在吗?@marcGravel:
任何类、接口、委托或数组类型
,是的。但这是原子性的。如果这还不能解决问题,你就必须执行断言。@32bitkid:这取决于OP说“类”和“其他东西”时的准确程度。@Will我会明白的,我是一个特殊性的粉丝。但是基于这个问题(它与“不是结构或枚举或模拟”)以及这个问题的文字标题(附加“c”)返回类型约束的msdn文档这一事实,我仍然会在这个答案上使用+1;它确保它实际上是一个引用,但并不确保t是一个类;它确保它是一个与OP的问题相关的引用对象,但默认值(T)不会给你一个T的副本,它会给你一个空白的新T。@VVS不,它不会-它会给
null
-但我很确定cyberzed打算把它理解为“TODO:你的代码在这里”这只是一个可以编译的东西…不过我得说我喜欢rep@marcgravel有正确的答案。这是正确答案的最奇怪的选择。代码不正确(好吧,签名是,但是
返回默认值(T)
应该被删除),它不包括任何引用,不是第一个答案,也不是最好的。。。现在我永远也赶不上了。事实上,这并不能保证t是一个阶级;它确保它是一个referenceYes-Marc,但这是OP在这里的意图。这取决于我们如何解释“保证T是一个类,而不是一个结构、枚举或其他东西”
接口
不是一个类;
代表
处于临界状态;任何一个都可以满足
T:class
你应该在这里重构你的评论:-)你只需要从我贪婪的手指上抓起我低垂的果实,砸碎它,不是吗?澄清:除了
中的t:class
约束之外,通常还使用
.IsClass
检查-后者处理大多数明显的故障。您可以根据需要进行粒度检查。他们可能犯了另一个常见错误,认为他们需要确保
T
是一个类,而他们真正需要做的是确保它是一个引用类型。在很多情况下,您不能使用值类型执行某些操作,但可以使用委托、接口或装箱值类型执行这些操作。@Jon同意;这一切都归结为OP在他们的问题中的确切含义——但在这里有两种含义的答案是有价值的,因为下一个发现问题的人可能有不同的意图
where T : class
if(!typeof(T).IsClass) throw new InvalidOperationException("T must be a class");