What is object casting?

前端 未结 3 1388
醉酒成梦
醉酒成梦 2021-01-17 03:36

I\'m a bit confused about what exactly object casting is and what it\'s used for. I\'ve read the MSDN documentation about Casting and type conversion, where I can see that f

相关标签:
3条回答
  • 2021-01-17 04:20

    You would cast to a specific object, whenever you want to use that specific type of object. Another way to cast to another type is

    SomeType x = obj as SomeType;
    

    Here you won't get an exception when obj is null. You should do a check for == null though.

    0 讨论(0)
  • 2021-01-17 04:31

    You only need to use the cast operator when there is no implicit cast available that the compiler can verify is safe. If there is one and the compiler is sure the cast will succeed then it will do it for you automatically.

    Now, why should I use a cast? You should use a cast when you either:

    • Have an object of type A and you need an object of type B and there is a way to convert an A into a B.
    • You have a reference of type A to an object and you need a reference of type B to that same object and both A and B are valid reference types to that object.

    Another way to think about it is:

    • When you know better than the compiler and you know an object is a type the compiler can't.
    • When an object is not of a certain type but you know there is a valid conversion to that type.

    And this brings up a way to group casts based upon what the cast is really doing:

    • Casts that preserve identity.
    • Casts that don't.

    The 1rst group are what we call reference conversions. These don't change the object at all, they simply change the type of the reference pointing to the object (evidently, they only apply to reference types, value types can not have reference conversions because you can't get a reference to a value type). Note that this type of cast is provided by the language itself, you can't implement reference conversions.

    The second group are all the conversions that entail a representational change in the object, that is, the bits of the object returned by the cast are different to the the bits of the casted object. These type of casts are the implicit and explicit operators you can implement in any C# class/struct.

    You can read more about this in this SO answer.

    Ok all that is very interesting, but can you give me concrete examples? Yes, of course:

    1. The compiler knows enough:

      interface IFoo { }
      class Foo: IFoo { }
      IFoo foo = new Foo();
      

      There is an implicit cast from Foo to IFoo in the last statement: IFoo foo = (IFoo)(new Foo());. This cast will succeed always and the compiler knows there is an implicit cast (a reference conversion) from Foo to IFoo available, so it will do it for you.

    2. I know better than the compiler:

      object o = "Hello"; //'compiler knows enough' as all types are derived from object
      var s = (string)o;
      

      Here I know o is really a string and I'm telling the compiler: even though you think o is an object, trust me, I know its a string.

      This is also a reference conversion. The string Hello isn't touched in any way, the only thing we are changing is the reference pointing to it.

    3. I know a given object of type A is convertible to another object of type B although no reference conversion exists.

      short s = 1;
      int i = s;
      

      Note that a short is not an int but there happens to be a method (a cast operator) that knows how to convert a short to an int. Here we have an implicit cast from short to int. s and i have very different bits, but somebody implemented the necessary logic that turns a short into an int.

      Now note that this is an implicit cast, you don't need to explicitly cast the short although nothing stops you from doing it. Its perfectly valid to do: int i = (int)s;.

      double d = 1.5;
      int i = (int)d;
      

      Here we have the same type of cast, but now its explicit. If you would have written int i = d you'd get a compile time error because the cast is not implicit.

      This brings up an interesting point that you seem to be conflating with casts; information loss. Its a good practice that implicit casts do not loose information while explicit cast are allowed to do so. This seems reasonable, you don't want the compiler to implicitly cast things losing information without telling you; when you cast a short into an int there is no risk, any short fits into an int. That is obviously not true when casting from double to int, hence the cast is implemented as explicit. (Note on implemented, this isn't enforced by the language, its a design decision of whoever wrote the class defining the cast operators).

    0 讨论(0)
  • 2021-01-17 04:31

    A simple valid example goes back to older versions of C#. List<T> didn't exist in that version and in order to store a collection of data you had to use a non-generic collection:

    static void Main(string[] args)
    {
       ArrayList list = new ArrayList();
       list.Add(1);
       list.Add(2);
       list.Add(3);
    
       int total = 0;
       foreach(object item in list)
          total += (int)item; // without casting, compiler never knows item is int
    
       Console.WriteLine("Total = {0}", total);
    }
    

    Another valid example is events, most events use the signature (object sender, EventArgs e). In order to access the elements of the sender, a button for example, then you need to cast:

    Button btn = (Button)sender;
    Console.WriteLine(btn.Text);
    

    It is a better practice to use the as operator over the normal casting to prevent null reference exception, but the above is just to provide valid examples.

    0 讨论(0)
提交回复
热议问题