问题标签 [generic-constraints]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
210 浏览

c# - 通用方法将新 T 添加到 T 列表

我正在尝试将通用列表传递给将向列表添加新项目的函数。我有以下精简示例:

调用它的方法有这个错误:

T' must have a public parameterless constructor in order to use it as parameter泛型类型或方法中的类型T'

我正在尝试做的事情可能吗?我觉得它一定是因为编译器不应该关心它是什么类型的列表 - 它只需要调用公共的无参数构造函数并将新实例添加到传入的现有列表中。

我猜问题是接口不能保证它的实现者会有一个公共构造函数,但即使我给它一个具体的类,我也会得到这个错误:

类型T' must be convertible toBayClass' 以便在泛型类型或方法中将其用作参数“T”

将非常感谢任何指针。

0 投票
2 回答
1495 浏览

c# - 是否可以定义一个“不可为空" C# 泛型方法中的约束?

在 C# 中,该Nullable<T>类型不满足where struct通用约束(而 AFAK 这在技术上是一个结构)。这可用于指定泛型参数必须是不可为空的值类型:

当然,Nullable<T>也不满足引用类型where class约束:

这是否可以定义一个约束,例如它必须是引用类型或值类型,但不是 Nullable 值类型?

像这样的东西:

0 投票
2 回答
274 浏览

c# - 构造/制作泛型类型并将类型约束转换为 struct-as-base-type 约束

通常我们不能将类型参数限制为T从密封类型(例如struct类型)派生。这将毫无意义,因为只有一种类型可以适合,因此不需要泛型。所以约束如下:

或者:

是非法的,这是有充分理由的。

但是,当约束到另一个类型参数时,有时会在另一个类型参数被“替换”为实际类型(恰好是密封的)时发生这种情况。考虑类:

这是很无辜的。在具体化中:

我们使TFromType等于string。这可能是有意义的。以外的其他成员M<>。但M<>本身仍然可以使用:代码:

将运行并写入:

到控制台。所以约束基本上变成了where TFromMethod : string,但事情仍然很好。

这个问题是关于如果TFromType是值类型会发生什么。所以这次我们这样做:

那么为什么不允许来自cand声明的调用呢?d毕竟strangeDate编译时类型TFromMethod被限制为DateTime. 所以肯定strangeDate是隐含的DateTime?毕竟,这适用于stringclass ExampleOne上面)。

我更喜欢在官方 C# 语言规范中提到相关位置的答案。

请注意,当尝试添加时d,键入strangeDate.Ad... 会使 IntelliSense(Visual Studio 的自动完成器)列出所有可访问的实例成员的列表DateTime,因此很明显 IntelliSense 认为调用d应该是合法的!

当然,在注释掉 and 之后,我们可以使用c( with and ),代码如下:dExampleTwoef

运行并写出:

0 投票
0 回答
205 浏览

c# - 编译器未强制执行通用 C# 约束

我在 Unity3D(在 C# 中)工作,我在其中定义了这个泛型类:

这是其他类派生自的单例类型的模板。

MonoBehaviour类包含太多的字段和方法,所以为了避免返回的 Singleton 实例(类型为 T)过于混乱,我定义了以下类型:

这一切都很好,但是以下新类型定义不会导致编译器错误:

通用约束声明 T 应该是 MonoBehaviour 和 I。在这种情况下它不满足,但没有编译器错误。这是为什么 ?

0 投票
3 回答
1684 浏览

c# - 泛型类的基类约束指定类本身

昨天,我正在向我的朋友解释 C# 的通用约束。在演示where T : CLASSNAME约束时,我做了这样的事情:

看到它编译真的很惊讶。然而,经过一番思考,我认为从编译器的角度来看它是完全合法的 -UnusableClass<T>与可以在此约束中使用的任何其他类一样多。

然而,这留下了几个问题:如何使用这个类?是否有可能

  1. 实例化它?
  2. 继承它?
  3. 调用它的静态方法int method

如果是,如何?

如果其中任何一个可能的,那将是什么类型T

0 投票
1 回答
856 浏览

c# - 具有多个约束和继承的 C# 存储库

我找不到类似的问题,但如果我错过了,请随时重定向我。我正在尝试熟悉存储库模式。

我会给你一个我试图不成功地工作的代码的例子。这些是代表我正在使用的实体的类和接口。

然后到存储库接口

通用存储库

然后是一个更具体的存储库,它应该处理从数据库加载用户:

我创建 DBUser 类只是为了将来可以自由创建 XMLUser 来处理不同类型的保存。它继承自 User,而 User 又继承自 AbsObj。它实现了 IAbsObj。尽管如此,当我尝试将创建的 DbUser 对象添加到列表时出现编译时错误,指出不可能从 DBUser 转换为 T。鉴于我认为这是可能的约束:我在这里缺少什么?提前感谢您的帮助!

0 投票
7 回答
7189 浏览

c# - 究竟什么是“特级”?

在未能获得以下内容进行编译后:

有错误

约束不能是特殊类“System.Array”

我开始想,究竟什么“特殊班级”?

System.Enum当人们在通用约束中指定时,他们似乎经常遇到相同类型的错误。我用 , 和 也得到了System.Object相同System.DelegateSystem.MulticastDelegate结果System.ValueType

还有更多吗?我在 C# 中找不到有关“特殊课程”的任何信息。

此外,这些类有什么特别之处以至于我们不能将它们用作泛型类型约束?

0 投票
1 回答
364 浏览

c# - 为什么这些“特殊课程”?

在阅读了这个询问“特殊类”到底是什么的问题后,我留下了一个问题,为什么选择并硬编码这六个类、 、和作为System.Object特殊System.Array类,以防止它们被用作泛型类或方法的约束.System.DelegateSystem.EnumSystem.ValueType

很容易理解为什么System.Object会在那里;所有类都继承System.Object,因此无需将其包含为约束。我不清楚的是为什么其他人被选为这个特殊类别的一部分。

PS:当尝试将特殊类用作约束时,会引发编译错误 CS0702。

0 投票
0 回答
38 浏览

c# - 为什么我在这里需要“类”约束

给定以下示例,我收到以下编译器错误:
Cannot apply operator '==' to type 'TEnumerable' and 'TEnumerable'

当我添加class约束

它按预期编译。


根据 MSDN,class约束意味着:

类型参数必须是引用类型;这也适用于任何类、接口、委托或数组类型。

但是IEnumerable<TItem>已经是一个reference type(所有接口都是引用类型),所以class约束没有增加进一步的限制。所以我的问题是:为什么我需要这个约束?

0 投票
2 回答
510 浏览

c# - C# - 类型约束和限制,保持类型安全的任何解决方法?

关于泛型类型约束的限制,我有一个非常常见的场景,需要定义另一个泛型。

已经讨论过(Eric Lippert 本人和其他人),但到目前为止,我还没有看到一般指导方针,或者说在遇到以下情况时可以应用的经验法则:

这很好,我们仍然有一些解决方法,方法是使用接口或构建新的基类,如下所示:

这很好,但是如果我想添加一个新的合法继承层会发生什么?

甚至更糟(代码显然无法编译)并且在没有真正的类型安全的情况下变得非常愚蠢:

那时人们通常会说不,设计不应该那么复杂......检查您的业务需求并使用大量接口与组合,继承不仅可以节省您编写一些额外的代码而且这些类应该形成某种形式家庭,好吧,他们确实形成了一个家庭。

好吧,很公平,但这并不能真正解决我不得不承认被过度夸大的情况,但在某些情况下,具有约束的继承是有意义的,并且这些约束也有约束。

是的,那些可能会让你非常疯狂(例如递归约束)并让你把你的头发拉出来......但仍然有一些情况可以方便,特别是在类型安全方面。

无论如何,关于这些约束,最适合遵循的一般指导方针是什么?除了使用接口或在构造函数中选择类型子集之外,还有其他解决方案吗?