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

时间:2017-01-20 10:12:37

标签: c#

如果我在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?

是否有任何情况会导致新对象无法保留它的引用?

3 个答案:

答案 0 :(得分:8)

取决于你在做什么演员。您可以想到两个主要的投射组:

  1. 保留身份的人
  2. 那些不
  3. 的人

    嗯,这不是很有帮助,这正是你所要求的。

    什么演员保留身份?所有那些需要在对象本身进行代表性更改的内容,即构成对象的 更改

    实施例?值类型之间的所有转换:intlongintdouble等,任何装箱或拆箱转换等。组成{{1与构成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); } 潜伏 无论它返回什么地方。多数民众赞成,马上告诉你 cast无法保留身份...您正在返回一个新对象。
    • 您无法实现用户定义的身份保留转换。这不是问题,因为没有需要,这些转换已经由C#的类型系统提供。

    那么,是什么身份保留演员表或转换?那些没有触摸对象的人; 参考转化

    咦?但等等,重点是我投射对象,怎么会这样?

    在参考转化中,您仅"施放"指向对象的引用。对象总是一样的。当然,这只在参考类型中有意义,这就是为什么价值类型不具有保持身份转换的身份的原因;除非它们是盒装的,否则没有对值类型的引用。

    实施例? newobjectstringFooIFooGiraffe等。

    请注意,引用类型也可以很好地实现用户定义的转换,但这些不会保留标识。

    所有这一切,这是拇指的规则:

    • 语言类型系统本身提供/允许的任何演员表都保留了身份。这些仅是参考转换,仅适用于参考类型。
    • 任何用户定义的强制转换,显式或隐式,保留身份(记忆,Animal是用户定义的强制转换,有人必须在类(long)2中实现它)。

    因此,在回答您的问题时,System.Int64是参考转化,这意味着var str = obj as stringReferenceEquals(str, obj); truestr指向完全相同的对象,唯一的区别是引用的类型。

答案 1 :(得分:3)

  1. 字符串是不可变的,因此您无法更改它们。但是,您可以创建新实例:

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

    请注意myString是一个与原始字符串无关的全新实例。因此,即使您为myString指定了不同的内容,这也不会影响依赖于原始实例的调用代码。

    在您的示例中,str.ToUpper()不会更改任何内容,因为ToUpper会返回新字符串,而不是更改当前(str)实例。

  2. 强制为同一个实例创建一个新的引用。因此,对实例的修改将反映在其所有引用中,无论是转换实例还是仅重新引用

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

    在最后一个语句之后,amyInstance都将属性MyProperty设置为4,因为变量amyInstance都参考同一个MyType

  3. 的实例

答案 2 :(得分:-2)

像这样改变你的方法,看看结果)

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