Are structs 'pass-by-value'?

前端 未结 9 1363
轮回少年
轮回少年 2020-11-30 23:43

I\'ve recently tried to create a property for a Vector2 field, just to realize that it doesn\'t work as intended.

public Vector2 Position { get;         


        
9条回答
  •  旧时难觅i
    2020-12-01 00:01

    Just to illustrate the different effects of passing struct vs class through methods:

    (note: tested in LINQPad 4)

    Example

    /// via http://stackoverflow.com/questions/9251608/are-structs-pass-by-value
    void Main() {
    
        // just confirming with delegates
        Action delegateTryUpdateValueType = (t) => {
            t.i += 10;
            t.s += ", appended delegate";
        };
    
        Action delegateTryUpdateRefType = (t) => {
            t.i += 10;
            t.s += ", appended delegate";
        };
    
        // initial state
        var structObject = new StructTransport { i = 1, s = "one" };
        var classObject = new ClassTransport { i = 2, s = "two" };
    
        structObject.Dump("Value Type - initial");
        classObject.Dump("Reference Type - initial");
    
        // make some changes!
        delegateTryUpdateValueType(structObject);
        delegateTryUpdateRefType(classObject);
    
        structObject.Dump("Value Type - after delegate");
        classObject.Dump("Reference Type - after delegate");
    
        methodTryUpdateValueType(structObject);
        methodTryUpdateRefType(classObject);
    
        structObject.Dump("Value Type - after method");
        classObject.Dump("Reference Type - after method");
    
        methodTryUpdateValueTypePassByRef(ref structObject);
        methodTryUpdateRefTypePassByRef(ref classObject);
    
        structObject.Dump("Value Type - after method passed-by-ref");
        classObject.Dump("Reference Type - after method passed-by-ref");
    }
    
    // the constructs
    public struct StructTransport {
        public int i { get; set; }
        public string s { get; set; }
    }
    public class ClassTransport {
        public int i { get; set; }
        public string s { get; set; }
    }
    
    // the methods
    public void methodTryUpdateValueType(StructTransport t) {
        t.i += 100;
        t.s += ", appended method";
    }
    
    public void methodTryUpdateRefType(ClassTransport t) {
        t.i += 100;
        t.s += ", appended method";
    }
    
    public void methodTryUpdateValueTypePassByRef(ref StructTransport t) {
        t.i += 1000;
        t.s += ", appended method by ref";
    }
    
    public void methodTryUpdateRefTypePassByRef(ref ClassTransport t) {
        t.i += 1000;
        t.s += ", appended method by ref";
    }
    

    Results

    (from LINQPad Dump)

    Value Type - initial 
    StructTransport 
    UserQuery+StructTransport 
    i 1 
    s one 
    
    
    Reference Type - initial 
    ClassTransport 
    UserQuery+ClassTransport 
    i 2 
    s two 
    
    //------------------------
    
    Value Type - after delegate 
    StructTransport 
    UserQuery+StructTransport 
    i 1 
    s one 
    
    
    Reference Type - after delegate 
    ClassTransport 
    UserQuery+ClassTransport 
    i 12 
    s two, appended delegate 
    
    //------------------------
    
    Value Type - after method 
    StructTransport 
    UserQuery+StructTransport 
    i 1 
    s one 
    
    
    Reference Type - after method 
    ClassTransport 
    UserQuery+ClassTransport 
    i 112 
    s two, appended delegate, appended method 
    
    //------------------------
    
    Value Type - after method passed-by-ref 
    StructTransport 
    UserQuery+StructTransport 
    i 1001 
    s one, appended method by ref 
    
    
    Reference Type - after method passed-by-ref 
    ClassTransport 
    UserQuery+ClassTransport 
    i 1112 
    s two, appended delegate, appended method, appended method by ref 
    

提交回复
热议问题