6

通过滥用 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
}
4

1 回答 1

2

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

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

这在SPARKAda和Java等主流语言中是众所周知的(通过 JML 扩展) - 由于 Microsoft Research 在代码合同功能方面的工作,它也可用于 C#。(我正在大量使用。我强烈建议观看 MSR 页面上链接的视频,它们是开始使用这些工具的最佳方式。)

The cccheck static checker from MSR can run in the background of Visual Studio, and will give you error and informational messages along with (I think purple) squigglies in your code editor.

If you want to go down that route, check out the Code Contracts MSDN forum for support - that's where most users seem to hang out.

于 2012-06-23T02:58:48.180 回答