C# 将逻辑建立在类型是结构的假设上是一种不好的做法吗?

C# 将逻辑建立在类型是结构的假设上是一种不好的做法吗?,c#,struct,C#,Struct,在我当前的项目中,我需要在充分理解什么是副本和什么是引用的情况下,抛出大量数据,特别是实施大量深度克隆。谢天谢地,我的很多数据都包含在简单的结构中,所以我可以将它们作为参数分配或传递,并确保它们不会相互引用 然而,我意识到正在执行的代码是基于这样的假设的,即这些类型是struct,并且如果有人打算在将来的某个时间将其类型更改为类,他们可能不会立即注意到错误,当他们这样做时,调试将是一场地狱 一般来说,我认为代码的正确性是基于假设在同一文件中没有明确地表示为一种气味,特别是当这个假设可以被改变而不

在我当前的项目中,我需要在充分理解什么是副本和什么是引用的情况下,抛出大量数据,特别是实施大量深度克隆。谢天谢地,我的很多数据都包含在简单的结构中,所以我可以将它们作为参数分配或传递,并确保它们不会相互引用

然而,我意识到正在执行的代码是基于这样的假设的,即这些类型是struct,并且如果有人打算在将来的某个时间将其类型更改为类,他们可能不会立即注意到错误,当他们这样做时,调试将是一场地狱

一般来说,我认为代码的正确性是基于假设在同一文件中没有明确地表示为一种气味,特别是当这个假设可以被改变而不立即破坏构建时。所以,这种情况对我来说真的很糟糕

我所做的真的是一个坏习惯吗?您是否经历过我在真实代码库中描述的任何问题,或者我在想象什么?如果你有,有什么好方法可以让事情更明确


下面是一个我正在谈论的示例(这是我的实际代码,所有名称都已更改,其他功能已被剥离):


DeepClone
方法是正确的,因为
Type
是一个枚举,而
OtherType
是一个结构,但您永远不会从这段代码中知道它。

您可以创建一个泛型约束,只允许结构,但不可创建,然后在需要假设的每个方法顶部创建该类型的变量

例如:

公共类AssumeStruct,其中tsstruct:struct
{
私有AssumeStruct(){}
}
然后:

public void MethodAssumingStructSemantics(S1 arg1)
{
   AssumeStruct<S1> t = null;
   ...
}
public void MethodAssumingStructSemantics(S1 arg1)
{
假设结构t=null;
...
}

如果以后更改了
S1
类型的性质,这将导致编译器错误。

如果使
struct
不可变(我认为这应该是不可变的),那么一旦
struct
成为类,就不会出现引用传播问题

除此之外,我认为您必须帮助
struct
的“维护者”和“用户”理解其含义

通过VisualStudio代码文档中的
备注
部分,您可以轻松做到这一点。这将在引用该类型的每个对象上弹出


我不会对代码进行太多更改,以显示数据类型是
结构
,或者进行一些类型检查。这可能只会导致混淆。

我认为您应该从可变性的角度来考虑数据,而不是从引用和副本的角度来考虑数据

如果你有一个不可变的类型,那么不管它是一个结构还是一个类,你都可以同样对待它,因为你知道它不能改变。您可以安全地传递它,而不必关心它是引用还是副本,这只是一个实现细节

每当您需要更改一个值时,不变性将迫使您创建一个副本。这样,您就永远不会把一个地方的值弄乱,而在另一个地方使用


String
类就是如何使用它的一个示例。由于字符串是不可变的,您可以将它们作为引用传递,而不会有字符串不断更改的风险。
String
类中对字符串进行更改的所有方法都将创建一个新字符串,并显示结果。

请发布一部分代码,以显示您已描述的内容。Thanks@Christos更新问题
public class AssumeStruct<TStruct> where TStruct : struct
{
    private AssumeStruct(){}
}
public void MethodAssumingStructSemantics(S1 arg1)
{
   AssumeStruct<S1> t = null;
   ...
}