views:

26

answers:

1

I am working on a projection utility and have one last (more?) hurdle to clear...

Here is the scenario:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? AddressID { get; set; }
    public Address Address { get; set; }
    public string Otherproperty1 { get; set; }
    public string Otherproperty2 { get; set; }
    public string Otherproperty3 { get; set; }
    public string Otherproperty4 { get; set; }
}

public class PersonSummary
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? AddressID { get; set; }
    public AddressSummary Address { get; set; }

}

public class Address
{
    public int AddressID { get; set; }
    public string HouseNumber { get; set; }
    public string StreetName { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int Zip { get; set; }
    public string Otherproperty1 { get; set; }
    public string Otherproperty2 { get; set; }
    public string Otherproperty3 { get; set; }
    public string Otherproperty4 { get; set; }
}

public class AddressSummary
{
    public int AddressID { get; set; }
    public string HouseNumber { get; set; }
    public string StreetName { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int Zip { get; set; }
}

I successfully have my utility working something like this:

ProjectionUtility.Project<Person,PersonSummary>();

Which will return this Expression Lambda:

p => new PersonSummary(){
    FirstName = p.FirstName,
    LastName = p.LastName,
    AddressID = p.AddressID,
    Address = p.AddressID.HasValue
        ? new AddressSummary(){ AddressID = p.Address.AddressID, HouseNumber = p.Address.HouseNumber, etc... }
        : new AddressSummary(){}
}

My goal is to be able to set Address = null if the AddressID.HasValue is false like so:

p => new PersonSummary(){
    FirstName = p.FirstName,
    LastName = p.LastName,
    AddressID = p.AddressID,
    Address = p.AddressID.HasValue
        ? new AddressSummary(){ AddressID = p.Address.AddressID, HouseNumber = p.Address.HouseNumber, etc... }
        : null
}

This is easily done "manually", however when I try to programatically create this lambda using expressions, I'm stuck...

I am currently using what essentially breaks down to this (I know the syntax isn't right, but I did it this way to in an attempt to show what it is I'm doing):

Expression.Condition(
    p.AddressID.HasValue,
    new AddressSummary(){},
    new AddressSummary(){});

If I try this:

Expression.Condition(
    p.AddressID.HasValue,
    new AddressSummary(){},
    null);

I can't because iftrue and iffalse must be the same type (AddressSummary) so I am stuck at the moment creating a new AddressSummary for the iffalse argument.

Any ideas?

Thanks!

+1  A: 

You need to cast your null to the correct type. In this case:

Expression.Condition(
    p.AddressID.HasValue,
    new AddressSummary(){},
    (AddressSummary)null);

null can be any (reference) type, but by default it is of type System.Object. If you want it to be another type, you have to tell it.

McKay
The OP's example is deeply flawed such that your answer is not accurate -- `Expression.Condition` only takes parameters of type `Expression`; there is no ambiguity so casting the `null` has no meaning.
Kirk Woll
Oh, yeah, good point. I guess I ignored syntax things because he said he knew the syntax wasn't right, and just tried to go with something based on the error message.
McKay
Thanks, your answer pointed me in the right direction...just needed to figure out how to create that using an expression and it worked like a charm. i.e. - var nullRef = Expression.TypeAs(Expression.Constant(null), typeof(AddressSummary)); which essentially translates to "null As AddressSummary".
Mike