簡體   English   中英

C# - cast是否保留對原始對象的引用?

[英]C# - Does casting preserve the reference to the original object?

如果我在C#中轉換對象,它是否仍然引用原始對象強制轉換?

例如,如果我創建一個方法來更改對象然后根據調用的特定實現強制轉換該對象,原始對象是否會被保留?

    public bool CallChangeString()
    {
        String str = "hello";
        ChangeObject(str);
        return String.Equals("HELLO", str);
    }

    public void ChangeObject(Object obj)
    {
        String str = obj as String;
        str.ToUpper(); // pretend for the sake of this that this changes str to upper case
    }

在這種情況下,String.Equals會返回true還是false?

是否有任何情況下,鑄造會導致新對象不保留它的參考?

取決於你在做什么演員。 你可以想到兩個主要的鑄造組:

  1. 那些保持身份的人
  2. 那些沒有

嗯,這不是很有幫助,這正是你所要求的。

演員保留身份? 所有那些需要在對象本身中產生代表性變化的東西,即構成對象的 改變

例子? 值類型之間的所有轉換: intlongintdouble等,任何裝箱或拆箱轉換等。構成long的位與構成int的位非常不同。

更多例子? 任何用戶定義的轉換運算符,顯式或隱式。 為什么? 因為編譯器不允許用戶定義的保留標識的轉換,因為編譯器已經為您執行了這些轉換:

class Foo : IFoo
{
     public static implicit operator object(Foo foo) => return foo; //Compile time error     
     public static implicit operator IFoo(Foo foo) => return foo; //compile time error.

     public static explicit operator Bar(Foo foo) => return new Bar(foo);
}

請注意用戶定義的強制轉換的一般模式:

  • 任何有效的運營商將永遠有一個new的不管它返回虎視眈眈。 這就是告訴你,演員不能保持身份......你正在回歸一個新的對象。
  • 您無法實現用戶定義的身份保留轉換。 這不是問題,因為沒有必要 ,這些轉換已經由C#的類型系統提供。

那么,什么身份保留演員或轉換? 好吧,那些接觸物體的人; 參考轉換

咦? 但等等,重點是我正在鑄造這個物體,那怎么可能呢?

在引用轉換中,您只是“轉換”指向對象的引用 對象總是一樣的。 當然,這僅在引用類型中有意義,這就是為什么值類型沒有保留轉換的身份的原因; 除非將它們裝箱,否則不會引用值類型。

例子? objectstringFooIFooGiraffeAnimal等。

請注意,引用類型也可以很好地實現用戶定義的轉換,但這些不會保留標識。

所有這一切,這是拇指的規則:

  • 語言類型系統本身提供/允許的任何強制轉換都保留了身份。 這些僅是參考轉換,僅適用於參考類型。
  • 任何用戶定義的強制轉換,無論是顯式的還是隱式的, 都不會保留標識(rememeber, (long)2是用戶定義的強制轉換,有人必須在System.Int64類中實現它)。

所以,回答你的問題, var str = obj as string是一個引用轉換,這意味着ReferenceEquals(str, obj)true ; strobj指向完全相同的對象,唯一的區別是引用的類型。

  1. 字符串是不可變的,因此您無法更改它們。 但是,您可以創建新實例:

     myString = myString.Replace("", "."); 

    請注意, myString是一個與原始字符串無關的全新實例。 因此,即使您為myString指定了不同的內容,這也不會影響依賴於原始實例的調用代碼。

    在您的示例中, str.ToUpper()不會更改任何內容,因為ToUpper返回一個新字符串而不是更改當前( str )實例。

  2. casting會為同一個實例創建一個新引用 因此,對實例的修改將反映在其所有引用中,無論是轉換實例還是僅重新引用

     var a = (MyType) myInstance; a.MyProperty = 4; 

    在最后一個語句之后, amyInstance都將屬性MyProperty設置為4 ,因為變量amyInstance引用了MyType的相同實例。

改變你的方法,看看結果)

public bool CallChangeString()
    {
        String str = "hello";
        ChangeObject(str);
        return String.Equals("HELLO", str);
    }

暫無
暫無

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

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