Laden...

Struct nicht immer ByValue!?

Erstellt von marcom vor 13 Jahren Letzter Beitrag vor 13 Jahren 610 Views
M
marcom Themenstarter:in
123 Beiträge seit 2007
vor 13 Jahren
Struct nicht immer ByValue!?

Hallo zusammen,

bis jetzt habe ich immer gedacht, dass structs nur "ByValue" übergeben werden, d.h. eine Kopie von dem Objekt bei jeder Methodenübergabe erstellt wird (es sei denn, man nutzt ref oder out, wovon ich aber erstmal nicht ausgehe).

Dann habe ich gelesen, dass structs auch Interfaces implementieren können und mich gefragt, was passiert, wenn ich in einer Methode, die nur das Interface kennt, das struct-Objekt erneut an eine andere Methode übergebe, die ebenfalls nur das Interface kennt. Und siehe da, plötzlich wurde nicht mehr eine Kopie des Structs übergeben, sondern die Referenz - d.h. es wurde keine Kopie von dem Objekt erstellt und alle Änderungen wurden auf dem Referenzobjekt ausgeführt!

Vielleicht wusstet ihr das, aber ich war doch sehr überrascht! Andererseits, woher sollte die Methode, die nur das Interface kennt, auch wissen, ob es sich um ein Ref- oder ValueType handelt...

(Deswegen hätte ich auch nicht direkt geglaubt, dass Structs Interfaces implementieren dürfen)

In diesem Sinne keine Frage von mir, nur eine Feststellung 😃

M
marcom Themenstarter:in
123 Beiträge seit 2007
vor 13 Jahren

Kleines Codebeispiel:


public interface IMy
{
    Int32 TestVar { get; }
    int Test();
}

public struct MyStruct : IMy
{
    public Int32 TestVar { get; private set; }

    #region IMy Members

    public int Test()
    {
        ++this.TestVar;
        return this.TestVar;
    }

    #endregion
}

static void Main()
{
    MyStruct m1 = new MyStruct();
    var val = m1.Test(); //val = 1
    Blub(m1);
    var val2 = m1.TestVar; //val2 = 1 (das hätte ich auch erwartet)

    IMy m2 = new MyStruct();
    val = m2.Test(); //val = 1
    Blub(m2);
    val2 = m2.TestVar; //val2 = 2 (!!)
}

static void Blub(IMy imy)
{
    var val = imy.Test();
}

Und noch was Interessantes (man achte auf den Unterschied bei der Variablendefinition von ms bzw. m1!)


MyStruct ms = new MyStruct();
IMy temp = ms;

var v1 = ms.Test(); //v1 = 1
var v2 = temp.Test(); //v2 = 1

IMy m1 = new MyStruct();
temp = m1;

v1 = m1.Test(); //v1 = 1
v2 = temp.Test(); //v2 = 2 (!!)

Hättet ihr damit gerechnet?

P
67 Beiträge seit 2008
vor 13 Jahren

Und das ganze nennt man dann Un/Boxing.
Hier wird das ganze einmal Erklärt.

gruß

Religionskriege sind Konflikte zwischen erwachsenen Menschen, bei denen es darum geht, wer den cooleren, imaginaeren Freund hat