Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 18, 2010 @ 16:45
    Jeroen Breuer
    0

    Linq to Umbraco cast to master bug

    Hello,

    I've got a document type which has master document type. In Linq to Umbraco this document type also inherits from the master document type. If I try to cast the object to it's master I get an empty object (not null, but all properties are empty). Example:

    BasePage basePage = (BasePage)employee;

    If I debug and I look at the employee object all properties are filled. If I look at the basePage object which it got casted to all properties are empty. Is this a bug?

    Jeroen

  • Berto 105 posts 177 karma points
    Aug 18, 2010 @ 17:32
    Berto
    0

    If you look into your UmbracoDataContext class, you will see that Employee (I think that's the name of your child type) class descends from the BasePage class 

    somthing like this

    public partial class Employee : BasePage

    So, when you cast to the father type, this doesn't have the properties of the child class and the cast fails.

    I tried to find some documentation about this in google, but I think i'm not using the right keywords

    Simple answer: It's not a bug, it just pure OOP (I think that there aren't any oop language that permits this, but i can be wrong)

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 18, 2010 @ 20:29
    Jeroen Breuer
    0

    @Berto I think this type of cast is possible if im not mistaken. Its called polymorphysm (http://en.wikipedia.org/wiki/Type_polymorphism). Just like you can convert an object to an interface you can also cast it to its parent. This Linq example should work. Maybe I should try to cast it to an interface.

    Jeroen

  • Berto 105 posts 177 karma points
    Aug 19, 2010 @ 00:15
    Berto
    0

    @Jeroen Breuer You are right! My bad! I tried a simple console project and yes, you can cast to the base class. I'm going to see more about this bug. 

    Thx for lesson ;)

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 23, 2010 @ 10:12
    Jeroen Breuer
    0

    Well I tried converting the object to an interface and that did work :D.

    This currently does not work:

    BasePage b = (BasePage)test;

    And this does work:

    IBasePage b = (IBasePage)test;

    Jeroen

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Aug 23, 2010 @ 10:30
    Aaron Powell
    0

    I *think* this was related to a bug in LINQ to Umbraco which I resolved yesterday - http://umbraco.codeplex.com/workitem/28537

    The problem is that the super class isn't really a super class, it's a full re-implementation of the subclass, so when you down-cast it the properties don't map across like they should.

    I had this same problem today and it wasn't until I saw this thread that I twigged as that this bug may be the cause of it.

    I'll do some more investigation but I'm pretty sure it was related to the above linked bug

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Aug 23, 2010 @ 10:41
    Aaron Powell
    2

    Ok, I can confirm that that was the problem.

    Because the properties of the sub class are generated on the super class when you set them it writes to the private instance field on the super type.

    When you down-cast to the sub class it wont transfer the fields across because it didn't know that it should do that.

    How to fix it before 4.5.2's LINQ to Umbraco code generator comes out

    As I mentioned above I've fixed it for the next Umbraco release and if you're not someone who likes to run pre-release code (I don't recommend it or support it) here's what you need to do:

    Note: This will not work if you're using the AutoExport to .NET package from Matt!!!

    1. Open your LINQ to Umbraco generated file
    2. Find your super class
    3. Delete any property and field which resides on the child type
    4. Save and compile
    Now the property/ properties only reside on the sub class so when you're setting properties they are actually set on the sub class, not the super class, meaning you can downcast it properly.
    Apologies for the bug, but good news is that it is fixed and there is a work around :P

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Aug 23, 2010 @ 11:05
    Matt Brailsford
    0

    Nice detective work =)

    Just to clarify, AutoExport2DotNet WON'T work IF you have the format set to DLL. If the format is set to CS, you are free to modify the code as you need.

    Matt

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 25, 2010 @ 11:03
    Jeroen Breuer
    0

    Now that is has been solved in the 4.5.2 beta which approach is the best?

    BasePage b = (BasePage)test;

    Or

    IBasePage b = (IBasePage)test;

    I only need the properties which are also available in the interface.

    So should I cast it to the parent class or to the interface?

    Jeroen

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Aug 25, 2010 @ 11:09
    Matt Brailsford
    1

    Hi Jeroen,

    Personally I'd probably stick with the

     IBasePage b = (IBasePage)test;

    as it should make your code more testable since you'll be able to easily swap out the concrete instance for a mock instance.

    Matt

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Aug 25, 2010 @ 11:19
    Jeroen Breuer
    0

    Thanks Matt,

    Will keep using the interface :).

    Jeroen

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Aug 25, 2010 @ 12:20
    Aaron Powell
    0

    It depends if you want the abstract version of a concrete class. Right tool for the right job ;)

Please Sign in or register to post replies

Write your reply to:

Draft