Question

I am using a derived class and casting the base class to it using the as keyword. When I do this, the derived class constructor is being called, and it's objects initialized, but the derived instance does not end up with the initialized objects (has nulls). Here's a code sample.

// classes
public class Request
{
  public Request();
  public Header Header{get;set;}
}

public class CreateRequest : Request
{
  public Foo Foo{get;set;}
  public Bar Bar{get;set;}

  public CreateRequest():base()
  {
    this.Foo = new Foo();
    this.Bar = new Bar();
  }
}

public class SomeClass
{
  private Response ProcessCreateRequest(Request request)
  {
    // request comes from a json request
    CreateRequest createRequest = request as CreateRequest;
    // values of Foo and Bar are null
    [...]
  }
}

Is the problem that "as" is normally used for derived->base and not base->derived or is there something else at work here?

Was it helpful?

Solution

until jon skeet shows up to correctly answer this question, as far as i know the 'as' keyword is just a way of doing a cast that suppresses exceptions if the cast is invalid; it should not call any constructors on its own

so have you verified (e.g. in the debugger) that the passed-in object is properly initialized before the cast?

OTHER TIPS

As a point of clarification the as operator does not call any methods on the object in question. It merely finds out if the object can be converted to the type requested, and if so returns the instance as the type or null if it cannot (see the C# Language Specification Section 7.9.11 "The as operator").

From the code you have displayed, it appears that there is no reason for the CreateRequest to have the null properties unless the JSON request deserialization method explicitly sets them to null. You can show that this is the case by calling:

var response = ProcessCreateRequest(new CreateRequest());
System.Diagnostics.Debug.Assert(response.Foo != null);
System.Diagnostics.Debug.Assert(response.Bar != null);

You will find both the as operator and the default constructor are working correctly.

The problem is that using 'as' doesn't call the constructor. It just casts the object to the new type (in this case, from Request to CreateRequest).

In your case, since Request doesn't have values for the fields...they are null after being cast.

You can't use the "as" keyword to convert an instance of a base class to an instance of a derived class. If the object wasn't an instance of the derived class to begin with, the "as" keyword won't convert it into one.

Also, in addition to what stephan has said, (using 'as' cannot trigger a constructor),

... in yr question, you state

" I am using a derived class and casting the base class to it ..."

You cannot cast a base class to a derived class, only the other way around, so clearly either (hopefully) you are mis-stating yr question, or your assumptions are invalid in some way. Can you be more explicit?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top