c# - 使用泛型在编译时强制执行有效结构

标签 c# generics types

通过滥用 C# 中的类型系统,我可以创建代码,其中编译器将强制执行规则,以确保不会执行不可能的操作。在下面的代码中,它特定于矩阵乘法。

显然下面是完全不切实际/错误的,但有没有理由我们不能在未来的 c# 中有这样的东西,我可以在其中定义像 Matrix<2,2> 这样的类型并让编译器确保安全?

此外,在任何主流语言中都存在这样的东西吗?我怀疑 C++ 中的元编程可能会发生类似的事情??

public abstract class MatrixDimension { }

public class One : MatrixDimension { }
public class Two : MatrixDimension { }
public class Three : MatrixDimension { }

public class Matrix<TRow, TCol>
    where TRow : MatrixDimension
    where TCol : MatrixDimension
{

// matrix mult. rule. N×M * M×P  = N×P 
    public Matrix<TRow, T_RHSCol> Mult<T_RHSCol>(Matrix<TCol, T_RHSCol> rhs)
        where T_RHSCol : MatrixDimension
    { return null;}
}

public class TwoByTwo : Matrix<Two, Two> { }

public void Main()
{
    var twoByTwo = new Matrix<Two, Two>();
    var oneByTwo = new Matrix<One, Two>();
    var twoByThree = new Matrix<Two, Three>();
    var threeByTwo = new Matrix<Three, Two>();
    var _twoByTwo = new TwoByTwo();

    var _2x2 = twoByTwo.Mult(twoByTwo);
    var _1x2 = oneByTwo.Mult(twoByTwo);
    var _3x3 = twoByThree.Mult(threeByTwo);

    var _2x2_ = _twoByTwo.Mult(twoByTwo);

    var invalid = twoByThree.Mult(twoByThree); // compile fails, as expected
}

最佳答案

F# 支持 units of measure内置于语言中 - 基本上是在 CLR 类型之上创建更丰富的类型系统,就像您开始使用泛型所做的那样。

构建更丰富的类型系统(我在自己的软件中使用它以确保核心模块的高可靠性和正确性)的一种不同的,我认为是互补的方法是将编译器与 < em>theorem prover 以确保满足方法和属性(以及类不变量)的前置条件和后置条件。

这在主流语言中是众所周知的,例如 SPARKAdaJava (via JML extensions) - 由于 Microsoft Research 在 Code Contracts 上的工作,它也可用于 C#特征。 (我经常使用它。我强烈建议观看 MSR 页面上链接的视频,它们是开始使用这些工具的最佳方式。)

来自 MSR 的 cccheck 静态检查器可以在 Visual Studio 的后台运行,并会在您的代码编辑器中为您提供错误和信息性消息以及(我认为是紫色的)波浪线。

如果您想走那条路,请查看 Code Contracts MSDN forum寻求支持 - 这似乎是大多数用户常去的地方。

关于c# - 使用泛型在编译时强制执行有效结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11165654/

相关文章:

c# - 如何在 C# 中正确使用 OpenID Connect jwks_uri 元数据?

c# - 无法将 Microsoft Office Interop 程序集添加到项目中

C# - 修改特定于每种类型的数据结构的通用函数

c++ - 在 C++ 中编写通用堆栈类

typescript - 两个相同的 TypeScript 接口(interface),但名称不同 - 如何使其干燥/避免重复?

c# - 在代码中的什么地方应该保存不变的数据?

c# - 如何下载文件

c# - 我可以从泛型类型 T 继承泛型类吗?像 MyClass<T> : T

python - 为什么在Python中对不同类型进行反转和排序?

java - 如何将其他语言的数据映射到java