首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ValueTuple结构是否仅作为变量可变?

ValueTuple结构是否仅作为变量可变?
EN

Stack Overflow用户
提问于 2017-05-08 16:15:45
回答 1查看 1.8K关注 0票数 4

我试着使用ValueTuple结构并尝试实现一个不可变的复合键。键由值类型组成。

到目前为止,我尝试用一些单元测试来破坏下面的实现,但没有成功。我是不是遗漏了什么?

而且,这只是出于好奇,我想介绍一下ValueTuple,它在.NET 4.7发布之前的局限性。

到目前为止,我对ValueTuple的理解是,作为变量,它只是可变的,而不是作为字段或属性。不过,不知道“可变”是什么意思。更改ValueTuple实例是否实际上创建了一个新的ValueTuple (就像字符串是“不可变的”但实际上是引用类型这一常识一样)?

来自https://stackoverflow.com/a/41084470/1154965 System.ValueTuple不仅是一个struct,它也是一个可变的struct,在使用它们时必须小心。想一想,当类将System.ValueTuple作为字段保存时会发生什么。

这里我的实现和测试

代码语言:javascript
复制
public interface IHaveCompositeKey
{
    (Guid id, string name) Key { get; }
}

public class ImmutableKey : IHaveCompositeKey
{
    public (Guid id, string name) Key { get; }
    public ImmutableKey((Guid id, string name) key) => Key = key;
    public override int GetHashCode() => Key.GetHashCode();
    public override bool Equals(object obj)
    {
        var a = obj as ImmutableKey;
        return a != null && Key.Equals(a.Key);
    }
}

[TestFixture]
public class KeyTests
{
    [Test]
    public void Test1() // passes
    {
        var key = (Guid.NewGuid(), "Foo");
        var a = new ImmutableKey(key);
        var b = new ImmutableKey(key);
        Assert.IsTrue(a.Equals(b));
        Assert.IsTrue(a.GetHashCode().Equals(b.GetHashCode()));
    }

    [Test]
    public void Test2() // passes
    {
        (Guid id, string name) key = (Guid.NewGuid(), "Foo");
        var a = new ImmutableKey(key);
        key.name = "Bar"; // mutable
        var b = new ImmutableKey(key);
        Assert.IsFalse(a.Equals(b));
        Assert.IsFalse(a.GetHashCode().Equals(b.GetHashCode()));
    }

    [Test]
    public void Test3() // does not compile
    {
        var key = (Guid.NewGuid(), "Foo");
        var a = new ImmutableKey(key);
        // compilation error
        a.Key.name = "Bar"; // immutable
        var b = new ImmutableKey(a.Key);
        Assert.IsFalse(a.Equals(b));
        Assert.IsFalse(a.GetHashCode().Equals(b.GetHashCode()));
    }
}

错误:不能修改'ImmutableKey.Key‘的返回值,因为它不是变量

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-08 19:48:59

在三种情况下,可以更改可变结构并查看结果:

  • 局部变量:MyStruct s = new MyStruct(); s.Prop = 4;
  • 另一种类型的字段:class MyType { public MyStruct S;} ... myType.S.Prop = 4;
  • 数组元素:MyStruct[] myArray =...; myArray[3].Prop = 4;

为什么post中的代码没有检测到更改代码使用的属性而不是字段。

注意,List<MyStruct>不允许修改,因为索引器(this[..])返回项的副本(因为没有像C++那样返回引用的支持)。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43852501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档