Search code examples
c#castingheap-memoryimplicit-conversionstack-memory

Implicit versus Explicit cast with parenthesis wrapper


The implicit cast:

FooType Foo = (FooType)someParameter; 

The Explicit cast:

FooType Foo = someParameter as FooType; 

However, Does double wrapping an implicit cast make it an explicit cast if directly accessing it's properties? Shown below...

string fooName = ((FooType)someParameter).Name; 

Nothing critical just curious because I remember reading about implicit casts only getting stored in one place (either stack or heap I forgot) but explicit casts stored it in two places taking up twice as much memory or something so now I try to avoid them if possible.

Nothing critical just curious because I remember reading about implicit casts only getting stored in one place (either stack or heap I forgot) but explicit casts stored it in two places taking up twice as much memory or something so now I try to avoid them if possible.


Solution

  • Both FooType Foo = (FooType)someParameter; and FooType Foo = someParameter as FooType; are explicit casts.

    This is an example of an implicit cast:

    void Main()
    {
        BarType bar = new BarType();
        FooType foo = bar;
    }
    
    class FooType { }
    
    class BarType : FooType { }
    

    Here is another example of an implicit cast:

    void Main()
    {
        int[] values = new int[] { 1, 2, 3 };
        
        Console.WriteLine(Sum(values));
    }
    
    int Sum(IEnumerable<int> source) => source.Sum();
    

    Implicit casts are ones that happen automatically without you needing to write explicit code to perform the cast.

    The difference between the two examples you gave are that FooType Foo = (FooType)someParameter; will throw an exception at run-time if someParameter cannot be cast to FooType at run-time, however the someParameter as FooType cast will return null if the cast is not valid.

    Also, take this example:

    void Main()
    {
        Foo f1 = new Foo(); IFoo f2 = f1;
    }
    
    interface IFoo { } class Foo : IFoo { }
    

    Here the new Foo() creates an instance of Foo (allocates memory) and then assigns a reference to that instance to f1. When f1 is assigned to f2 a copy of the reference is made. So you end up with a memory allocation and two references to that memory.

    That always happens with refence types - regardless of anything to do with implicit or explicit casts.