代码之家  ›  专栏  ›  技术社区  ›  Andrzej Gis

有没有办法通过引用来比较2个ref结构?

  •  2
  • Andrzej Gis  · 技术社区  · 7 年前

    ref 这样会更有意义。

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

    给定MyStruct是一个标准结构

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

    var comparison1 = ReferenceEquals(refFoo, refBar); ,我明白了 因为我传递的是值类型,所以值总是false。

    如果我使用C#7 ref struct

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

    当我尝试这个: var comparison1=ReferenceEquals(refFoo,refBar); ,我得到一个 MyStruct 不可分配给参数类型 object . 如果我试着做同样的事情: var comparison1 = ReferenceEquals(foo, bar);

    最后一个例子是什么时候 引用结构 但是 refFoo refBar 裁判

    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; }
    }
    
    • 那么,是否有一些通过引用比较结构的秘密方法?
    1 回复  |  直到 7 年前
        1
  •  1
  •   Dudi Keleti    7 年前

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

    每个值都将装箱,因此结果始终为false。

    var comparison1=ReferenceEquals(refFoo,refBar); var comparison1 = ReferenceEquals(foo, bar);

    ref 无法装箱或拆箱(如@PetSerAl所写)。

    最后一种情况是MyStruct是ref struct,但是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}");
            }
        }
    }
    
    推荐文章