有没有办法通过参照比较2 REF结构?

问题描述 投票:2回答:1

最近,我游荡,如果有可能通过参照比较结构。在阅读一个结构体变量创建变量的副本,通过比较参考标准结构似乎是不可能的。然而,使用C#7 refs会更有意义。

我定义4个变量

MyStruct foo = new MyStruct(){SomeInt = 1};
ref MyStruct refFoo = ref foo;

MyStruct bar = new MyStruct() { SomeInt = 2 };
ref MyStruct refBar = ref foo;

Given MyStruct is a standard struct

struct MyStruct
{
    public int SomeInt { get; set; }
}

当我试试这个:var comparison1 = ReferenceEquals(refFoo, refBar);,我得到警告说,值始终为false,因为我传递值类型。

If I use C# 7 ref struct instead

ref struct MyStruct
{
    public int SomeInt { get; set; }
}

当我试试这个:var comparison1 = ReferenceEquals(refFoo, refBar);,我得到一个编译错误说MyStruct是不能分配给参数类型object。如果我尝试同样的事情:var comparison1 = ReferenceEquals(foo, bar);

The last case is when MyStruct is ref struct, but refFoo and refBar variables are declared without ref. (I get the same error as in the 2nd case)

static void Main(string[] args)
{
    MyStruct foo = new MyStruct(){SomeInt = 1};
    MyStruct refFoo = foo;

    MyStruct bar = new MyStruct() { SomeInt = 2 };
    MyStruct refBar = foo;

    var comparison1 = ReferenceEquals(refFoo, refBar);

}

ref struct MyStruct
{
    public int SomeInt { get; set; }
}
  • 那么,有没有参照比较结构的一些偷偷摸摸的?
  • 奖金的问题:为什么只有第二和第三个例子给我一个编译错误?
c# c#-7.2
1个回答
1
投票

var comparison1 = ReferenceEquals(refFoo, refBar);,我得到警告说,值始终为false,因为我传递值类型

每个值将盒装所以结果始终为false。

var comparison1 = ReferenceEquals(refFoo, refBar);,我得到一个编译错误说MYSTRUCT是不能分配给参数类型的对象。如果我尝试同样的事情:var comparison1 = ReferenceEquals(foo, bar);

ref不能盒装或拆箱(像@PetSerAl写)。

最后一种情况是,当MYSTRUCT是裁判结构,但refFoo和refBar变量无需REF声明。 (我得到同样的错误作为第二种情况)

同上。

奖金的问题:为什么只有第二和第三个例子给我一个编译错误?

我敢肯定,现在你明白了。

那么,有没有参照比较结构的一些偷偷摸摸的?

如果你的意思比较地址,这里有一些例子:

class Program
{
    struct Struct { public int Value { get; set; } }
    ref struct RefStruct { public int Value { get; set; } }

    static unsafe void Main(string[] args)
    {
        var @struct = new Struct { Value = 5 };
        var struct2 = @struct;
        ref Struct struct3 = ref @struct;
        Struct* p = &@struct;
        Struct* p2 = &struct2;
        Console.WriteLine($"struct  address is: {(int)p} struct  value is {p->Value}");
        Console.WriteLine($"struct2 address is: {(int)p2} struct2 value is {p2->Value}");
        fixed (Struct* p3 = &struct3)
        {
            Console.WriteLine($"struct3 address is: {(int)p3} struct3 value is {p3->Value}");
        }

        Console.WriteLine();
        Console.WriteLine($"struct and struct2 Unsafe.AreSame? {Unsafe.AreSame(ref @struct, ref struct2)}");
        Console.WriteLine($"struct and struct3 Unsafe.AreSame? {Unsafe.AreSame(ref @struct, ref struct3)}");
        Console.WriteLine();

        var structAsPointer = Unsafe.AsPointer(ref @struct);
        var struct2AsPointer = Unsafe.AsPointer(ref struct2);
        var struct3AsPointer = Unsafe.AsPointer(ref struct3);
        Console.WriteLine($"struct AsPointer and struct2 AsPointer are same? {structAsPointer == struct2AsPointer}");
        Console.WriteLine($"struct AsPointer and struct3 AsPointer are same? {structAsPointer == struct3AsPointer}");
        Console.WriteLine();

        var refStruct = new RefStruct { Value = 7 };
        var refStruct2 = refStruct;
        RefStruct* p4 = &refStruct;
        RefStruct* p5 = &refStruct2;
        Console.WriteLine($"refStruct  address is: {(int)p4}, refStruct  value is: {p4->Value}");
        Console.WriteLine($"refStruct2 address is: {(int)p5}, refStruct value is: {p5->Value}");

        ref RefStruct refStruct3 = ref refStruct;
        fixed (RefStruct* p6 = &refStruct3)
        {
            Console.WriteLine($"refStruct3 address is: {(int)p6}, refStruct3 value is: {p6->Value}");
            Console.WriteLine();
            Console.WriteLine($"refStruct and refStruct2 are same? {&refStruct == &refStruct2}");
            Console.WriteLine($"refStruct and refStruct3 are same? {&refStruct == p6}");
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.