Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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# 如何强制字段/属性表示某种类型的物理量?_C# - Fatal编程技术网

C# 如何强制字段/属性表示某种类型的物理量?

C# 如何强制字段/属性表示某种类型的物理量?,c#,C#,在某些类型的代码(例如模拟/游戏/优化)中,存储、操纵和显示对象的许多物理量/属性(位置、速度、距离、面积、体积、时间、时差)。在这些类型的代码中,所有这些量通常用浮点数表示,即c#中的双精度数 这允许您将时间添加到距离,将面积添加到体积,将时间添加到时间,将位置添加到位置 但你永远不想这么做。您只需要将时间差添加到时间,将距离添加到其他距离或位置,并将面积与距离相乘。尽管如此,还是很容易出错,特别是当其他人编写代码时 有许多方法可以缓解这种危险。您可以定义表示各种物理量的自定义类,然后以编程方

在某些类型的代码(例如模拟/游戏/优化)中,存储、操纵和显示对象的许多物理量/属性(位置、速度、距离、面积、体积、时间、时差)。在这些类型的代码中,所有这些量通常用浮点数表示,即c#中的双精度数

这允许您将时间添加到距离,将面积添加到体积,将时间添加到时间,将位置添加到位置

但你永远不想这么做。您只需要将时间差添加到时间,将距离添加到其他距离或位置,并将面积与距离相乘。尽管如此,还是很容易出错,特别是当其他人编写代码时


有许多方法可以缓解这种危险。您可以定义表示各种物理量的自定义类,然后以编程方式禁止某些类型的交互。或者您遵守严格的命名约定(例如延迟时差)。在什么情况下(如果有的话),这两个选项中哪一个是最好的?如何实现第一个选项?如何为第二个选项命名

通常使用第二个选项,但更多是为了方便。命名成为一个问题,让你清楚地知道你在处理什么,即:命名属性
区域
,但即便如此,还是有一个单位问题

您可以通过创建一整套自定义类(或不可变结构类型)来处理第一种情况,以处理每种不同的组合,这可以很好地工作,但会使代码更加麻烦。框架中的
DateTime
struct就是一个很好的例子——在其核心,它基本上只是一个长整型值,但它被包装到一个struct中,以防止它被用作时间上的某个时刻


请注意,其他语言也有这样的选项—例如,F允许在语言级别处理,但C中不以任何方式支持这一点。

我认为最好将它们实现为结构,而不是类,因为它们是值类型。您需要执行运算符重载,以确保针对相同类型和不同类型的其他结构可以使用适当的运算符。您可能还希望重载ToString函数以输出标量值,可能需要使用单位


您还可以创建用于创建其他结构向量的通用结构-这些结构可以是二维(x和y属性)、三维(x、y和z属性)或N维(值数组)。这些结构还可以使用适当的运算符重载来执行向量计算。如果你做得正确,这将是一种与数据交互的非常自然的方式。

你所描述的两个选项都是可行的,但它们都有缺点。第一个选项会导致太多的类(然后需要定义很多关系),第二个选项很容易出错

一个更好的选择是创建一个自定义类,它既封装了一个浮点数,也封装了一个单元及其多重性的列表。例如,每秒1米可能变成{n=1,类型={length:1,time:-1}。然后,您可以强制执行,除非数字的单位相同,否则不能对其进行比较、添加或减去。乘法和除法将匹配类型的多样性相加

例如


相对“最简单”的方法是检查所需的计算,然后可能与C#进行互操作,我不知道有什么简单的方法可以只在C#中完成。只需补充:F#的单位不会导出到生成的程序集,所以使用此功能的唯一方法是将所有相关代码保留在F#中。@BrianRasmussen是的,这就是为什么我真的说“在C#中不受任何支持”-如果您完全停留在F#领域内,这是很好的,但一旦您尝试进行互操作,它就毫无用处了:(还值得指出的是,您可以使用运算符重载智能地返回相关类型。在物理库中,您可以重载运算符,例如,将位移1d除以时间返回速度1d,将位移2d除以时间返回速度2d,将位移3d除以时间返回速度3d,将速度xd除以时间返回加速度1drationXD,乘以质量返回力等。这是一种非常有用的方法,可以在某些系统中的计算中添加额外的双重检查。我同意structs的观点,并重载操作。这就允许出现类似jleahy所描述的场景,其中可以将速度乘以时间跨度,得到距离这最大的好处是编译时类型检查。
1 m/s * 4 seconds = 4 meters
{n=1, types={length:1, time:-1}} * {n=4, types={time:1}} = {n=4, types={length:1,time:0}}