簡體   English   中英

結構和接口中的C#getters / setter

[英]C# getters/setters in structs and interfaces

我來了(根據我)C#中的結構和接口之間的奇怪區別。 考慮這個接口和結構:

public interface INumber
{
    void ChangeNumber(int n);
    void Log();
}
public struct Number : INumber
{
    private int n;
    public void ChangeNumber(int n)
    {
        this.n = n;
    }
    public void Log()
    {
        Console.WriteLine(this.n);
    }
}

當我使用Number作為屬性創建一個新類時,使用ChangeNumber方法將n更改為2並使用Log打印該數字,它將打印0:

public class NumberContainer
{
    public Number Number { get; set; }
    public NumberContainer()
    {
        this.Number = new Number();
        this.Number.ChangeNumber(2);
        this.Number.Log();              //prints 0...
    }
}

過了一會兒,我意識到這是因為我打電話給this.Number.ChangeNumber(2); ,我實際上創建了一個新對象(因為getter)並將該數字更改為2.但后來我通過將Number屬性更改為INumber屬性來更改了一些代碼:

public class NumberContainer
{
    public INumber Number { get; set; }
    public NumberContainer()
    {
        this.Number = new Number();
        this.Number.ChangeNumber(2);
        this.Number.Log();              //prints 2!
    }
}

在這種情況下,它打印2! 為什么會這樣? 結構的相同原理是否適用於界面?

不同之處在於struct用作值類型,其中interface (可以通過類或結構實現)是引用類型。

這對你的例子產生了巨大的影響。 在第一種情況下你正在做什么調用this.Number意味着“獲取數字的值” - 這意味着它在堆棧上提取值,並且堆棧上的(未命名的)變量(不存儲在任何地方)得到改性。

在另一種情況下,接口是一個引用類型 - 這意味着它獲取存儲在其地址上的任何內容並對其進行修改。

一般來說,我不建議使用可變struct (如評論中已提到的)。

你可以在這里閱讀更多關於這個主題的內容,例如: 為什么可變結構“邪惡”?

這是由NumberContainer類中的auto屬性引起的,當您訪問屬性時,總是會獲得值的副本。

如果將屬性更改為字段,則按預期工作 請記住,autoproperty只是一對方法,並且在返回/傳遞給任何方法時都會復制該值類型。

當你打電話的時候

        this.Number.ChangeNumber(2);
        this.Number.Log();              //prints 0...

你實際上是在打電話:

 this.getNumber() // returns copy of value type
        .ChangeNumber(2); // executes op on that copy

    this.getNumber()
        .Log();

當您使用接口時,您將返回對對象的引用,因此始終對同一對象執行操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM