我知道C#得到了很多并行编程支持,但目前还没有用于副作用验证的 struct ,对吗?

我想现在C#已经布置好了,这就更棘手了.但是有没有计划把这个放进go ?或者F#是唯一的.NET语言,该语言具有用于验证副作用的 struct ?

推荐答案

C#语言不是,但是.NET的框架可能是.

合同库+中引入的静态分析工具.NET 4可能会引入以下内容:

微软现在在.NET3.5框架中使用[不可变]和[纯].

例如,请参见System.Core.dll中的[Microsoft.Contracts.Immutable]和[Microsoft.Contracts.Pure].不幸的是,它们是内部的.然而,Microsoft.Contracts.*主要诞生于Spec#研究,而Spec#已被合并到将成为.NET4.0一部分的Contracts API中.

我们会看到结果的.我还没查过预发布的版本.NET 4.0位包含任何API,如合同API中的[Pure]或[Immutable].如果他们这样做了,我想静态分析工具将是执行规则的工具,而不是编译器.

edit我刚刚加载了微软.合同.本周latest pre-release drop of MS Code Contracts强的dll.好消息:[Pure]和[Mutability(Mutability.Immutable)]属性存在于库中,这表明它们将在库中.NET 4.0.呜呜!

edit 2现在.NET4已经发布了,我查找了这些类型.[Pure]仍在System.Diagnotics.Contracts命名空间中.它不是用于一般用途,而是用于契约API的前置和后置条件判断.它不是编译器强制的,neither does the Code Contract checker tool enforce purity.[易变性]已经消失了.有趣的是,当Microsoft在.NET3.5中使用Mutability和Pure属性时(在System.Core.dll的内部BigInteger类中),.NET4将BigInteger移到了System.Numerics中,并从该类型中go 掉了[Pure]和[Mutability]属性.Bottom line: it appears .NET 4 does nothing for side-effects verification.

edit 3最近(2011年底)预览的微软Rosyln编译器即服务工具(据信将在Visual Studio 2015中用于RTM)看起来可以支持这样的东西;您可以向编译器编写扩展来判断纯度和不变性,如果使用这些属性修饰的内容不符合规则,则可以发出编译器警告.即便如此,我们仍在考虑几年后支持这一点.

edit 4现在Rosyln已经在这里了,从2015年夏天开始,构建纯/不变性编译器扩展的能力确实存在.然而,这对现有的框架代码和第三方库代码都没有任何作用.但是在地平线上的是C# 7 proposal for immutable types.这将由编译器强制执行,并将在C#中引入一个新的immutable关键字,并在.NET框架中引入一个[不可变]属性.用法:

// Edit #4: This is a proposed design for C# 7 immutable as of June 2015.
// Compiler will implicitly mark all fields as readonly.
// Compiler will enforce all fields must be immutable types.
public immutable class Person
{
    public Person(string firstName, string lastName, DateTimeOffset birthDay)
    {
        FirstName = firstName; // Properties can be assigned only in the constructor.
        LastName = lastName;
        BirthDay = birthDay; 
    }

    public string FirstName { get; } // String is [Immutable], so OK to have as a readonly property
    public string LastName { get; }
    public DateTime BirthDay { get; } // Date is [Immutable] too.
}

edit 5现在是2016年11月,似乎不可变类型从C#7中删除了.C#8总是有希望的.:-)

edit 6现在是2017年11月.C#8即将全面亮相,虽然我们不会有纯函数,但我们将拥有readonly structs个函数.这使得 struct 不可变,从而允许进行多个编译器优化.

edit 7现在是2020年7月,C#9将支持records,这是完全不变的类型.此外,记录将有With个表达式,用于从现有记录创建新记录以表示新状态.

edit 8是2021年11月,C 10已经发布,支持With个 struct 表达式,以及record个 struct .这些也有助于创建不可变的类型.

.net相关问答推荐

dotnet 8 web api在部署到docker后无法工作

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

为什么脚本不从 _Layout 加载并且必须添加到部分视图中?

在 C# 中,如何使用泛型的基类将泛型接口的所有实例注入到单个构造函数中?

为什么具有可为空值的 struct 的 HashSet 非常慢?

在 C# 中生成随机小数

使用字典作为数据源绑定组合框

发布版本中的 Debug.WriteLine

如何以编程方式判断类型是 struct 还是类?

XmlNode 值与内部文本

如何右对齐 DataGridView 列中的文本?

如何从 .net 中的数组类型获取数组项类型

多个等待与 Task.WaitAll - 等效?

如何判断对象是否是某种类型的数组?

无法将文件 *.mdf 作为数据库附加

ObservableCollection<> 与 List<>

关于 Enumerable.Range 与传统 for 循环的 foreach 的思考

何时使用抽象类?

将日期时间转换为时间跨度

安装带有恢复操作的 Windows 服务以重新启动