强行封class

Forcing a sealed class

在 C# 中是否可以通过接口或通配符强制密封 class?例如:

public interface A<SealedItem> where SealedItem : sealed

或者类似的东西:

public sealed interface A {}
public class B : A // B is now sealed.

这听起来可能很奇怪,但我想 "force" 一个密封的实例来改变约定。有这样的东西吗?

额外上下文:我有通过 API 公开的请求对象。我只将请求对象用于 "reading" 数据。这些请求对象可能会随着时间的推移而改变,但是,我不希望这些请求对象相互影响。在我的请求对象中使用继承会导致 "problems"。所以我想 "forcing" 密封的 class 对我来说会很好。

为什么继承在我的情况下可能不好:假设我有以下要求:

public class RequestA { public int Number { get; set; } }
public class RequestB : RequestA { public int Id { get; set; } }

两个请求都使用了本例中的值 number。假设 RequestA 的实现发生了变化,它不再需要 number 值。我的请求 B 代码现在将中断(只是一个小例子)。另一个例子是当 RequestA 得到一个新的 属性 时,请求 B 没有使用它。我现在在我的 RequestB 的逻辑中有一个未使用的 属性。

不,不是。

顺便说一句,你不继承接口,你实现接口,即你只是提供空方法的实现。

不,不可能。

class 是 sealed 的事实仅仅意味着它不能被继承。

For example something like: public interface A<SealedItem> where SealedItem : sealed

您只能对控制类型使用方式的事物使用通用约束 - 如果它是 class 或结构,如果它实现接口或派生自特定类型,或者如果它具有public 不带参数的构造函数。

or maybe something like: public sealed interface A {}

接口不能标记为 sealed

你可以做的一件事来防止继承是使用值类型 - 结构不能从除 ValueType 特殊 class 以外的任何东西继承(这超出了你的控制范围),也不能从 -
继承 来自 Structs (C# Programming Guide):

A struct cannot inherit from another struct or class, and it cannot be the base of a class.

然而,在大多数情况下,这可能不是一个好的选择,尤其是当您的代码中需要引用类型语义时(在大多数情况下,您确实需要)。

更新 - 随后更新问题:

Extra context: I have request objects that are exposed through an API. These request objects may change over time, however, I don't want these request objects to influence each other.

您可以将所有请求 class 都创建为密封的 - 并在代码中留下注释以供将来开发请求应密封并解释原因 - 但除了使用结构之外,您可能只能这样做而不是 classes(这可能不是一个坏主意,如果它仅用于 API 请求。)

查看 Choosing Between Class and Struct 以查看您的请求是否符合准则:

✓ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.

X AVOID defining a struct unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (int, double, etc.).
  • It has an instance size under 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.

In all other cases, you should define your types as classes.