4

I've just run across some code I don't understand. It is effectively

Class c = new BaseClass() as Class;

I don't understand the advantage of doing this, so I created my own console application to see what it does.

namespace Initialize
{
    class Program
    {
        static void Main(string[] args)
        {
            Demo demo = new Demo();
            demo.BaseProp = "";
            demo.DemoProp = "";

            BaseDemo baseDemo = new BaseDemo();
            baseDemo.BaseProp = "";

            BaseDemo baseDemo2 = new Demo();
            baseDemo2.BaseProp = "";

            BaseDemo baseDemo3 = new Demo() as BaseDemo;
            baseDemo3.BaseProp = "";

            //fails runtime
            //Demo demo2 = (Demo)baseDemo;

            Demo demo3 = (Demo)baseDemo2;
            demo3.BaseProp = "";
            demo3.DemoProp = "";

            Demo demo4 = (Demo)baseDemo3;
            demo4.BaseProp = "";
            demo4.DemoProp = "";
        }
    }

    class BaseDemo
    {
        public string BaseProp { get; set; }
    }

    class Demo : BaseDemo
    {
        public string DemoProp { get; set; }
    }
}

I can only assume this offers some additional help in relation to polymorphous but I can't work out how or see any difference between:

BaseDemo baseDemo2 = new Demo();  

and

BaseDemo baseDemo3 = new Demo() as BaseDemo;
Charles
  • 50,943
  • 13
  • 104
  • 142
Dave
  • 8,163
  • 11
  • 67
  • 103
  • Since I am struggling to think of why this was done.. let me just throw this out there: we have random crap like this with no rhyme or reason throughout our (inherited) code base. I wouldn't be surprised if there was no actual intention here.. and just a lack of understanding. – Simon Whitehead Aug 21 '13 at 13:22
  • As written, `Demo d = new BaseDemo() as Demo;` is guaranteed to be equivalent to `Demo d = null;` Either you are missing/misunderstanding some part of the code, or the developer built a code that has zero hope of working. – Sergey Kalinichenko Aug 21 '13 at 13:22

4 Answers4

4

This

Class c = new BaseClass() as Class;

is totally useless. If Class is a base class of BaseClass then the cast was automatic, otherwise the cast will always return null.

Class c = new BaseClass()

was enough... Single exception:

var c = new BaseClass() as Class;

now c is a reference of type Class (but referencing a BaseClass). You are forcing the type of an implicit typed variable (quite useless... you could have written directly Class c = new BaseClass();)

Note that the as keyword, contrary to the cast operator () doesn't "activate" the implicit/explicit cast operator that one of the two classes could have implemented.

This won't compile:

class BaseClass
{
    public static implicit operator Class(BaseClass b)
    {
        return new Class();
    }
}

class Class
{            
}

Class c = new BaseClass() as Class;

As written in the msdn:

The as operator is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception.

and

Note that the as operator performs only reference conversions, nullable conversions, and boxing conversions. The as operator can't perform other conversions, such as user-defined conversions, which should instead be performed by using cast expressions.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Actually, it has 1 point! To avoid interfaces I think... By doing this, it ensures the type is of a desired type (demo) bur only allows it to set the properties of the bass class! This has given my head pins and needles and seems some what overly complex and very unintuitive! However, thank you for you answer, it now makes sense! – Dave Aug 21 '13 at 14:03
1

You're right, in your case there is no difference. By using as you're just stating an obvious fact, that a Demo instance is also an instance of BaseDemo.

The as keyword is useful in other contexts, especially when you want to test if an object is of a certain type and then use it if the cast is successful.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Artur Krajewski
  • 571
  • 1
  • 4
  • 18
0

Casting with as returns null if the cast fails. It is a safe way to cast and check for a null instead of throwing an exception.

I am struggling to think of why your examples would ever be used..

Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138
  • 1
    But a constructor never returns `null`, so the cast is redundant. – Ahmed KRAIEM Aug 21 '13 at 13:09
  • 1
    I'm sorry, how can `Class c = new BaseClass() as Class;` ever be null? I could see if I did 'Class c;' but the fact I'm initializing it means (I think) it's initialized (and therefore not null)? – Dave Aug 21 '13 at 13:09
  • Indeed. I am struggling to come up with a reason anyone would do this. – Simon Whitehead Aug 21 '13 at 13:09
  • I've made an update which has confused me more, but is more accurate. – Dave Aug 21 '13 at 13:16
  • `Class c = new BaseClass() as Class;` is `null` because the cast fails as `BaseClass` is _not_ `Class` making the expression `new BaseClass() as Class` eveluate to `null`; hence `c == null`. – Ahmed KRAIEM Aug 21 '13 at 13:25
  • @Ahmed I know what the code evaluates to.. what I don't understand is why someone would write this. – Simon Whitehead Aug 21 '13 at 13:27
  • @SimonWhitehead I'm replying to Dave, see his comment. (sorry, I should've used [at]Dave Rook) – Ahmed KRAIEM Aug 21 '13 at 13:29
0
BaseDemo baseDemo2 = new Demo();  
BaseDemo baseDemo3 = new Demo() as BaseDemo;

There is absolutly no difference, just like there is no difference between if (condition == true) and if (condition)

A Demo is a BaseDemo so the safe cast (as) is redundant in this case.

On the other hand:

Class c = new BaseClass() as Class;

with Class extending BaseClass the cast would fail, making c null.

Ahmed KRAIEM
  • 10,267
  • 4
  • 30
  • 33