tags:

views:

95

answers:

2

I have a function which takes a generic:

public static ShowTrackChangesViewModel CreateVM<T>(IList<TrackChanges> TrackChanges, T entity)
        {
            //How do i access T properties ?

        }

T here is an entityFramework object. How do i cast it back to the real one to access its property ? Do i need to write a big if code ? Thx

+8  A: 

You can add this little gem to say that T should be an object of type MyBaseType:

public static ShowTrackChangesViewModel CreateVM<T>(IList<TrackChanges> TrackChanges, T entity) where T : MyBaseType

Then, you can use entity as if it were a MyBaseType. If you need specific properties that aren't in a base class, then you don't want a generic method (because it wouldn't be generic!).

Hope that helps!

Kieren Johnstone
+2  A: 

To be honest, I don't think generics are appropriate for your situation, at least not from what I can determine from your question.

The suggestion to constrain T:

public static ShowTrackChangesViewModel CreateVM<T>(IList<TrackChanges> TrackChanges, T entity) where T : MyBaseType

is equivalent to the simpler:

public static ShowTrackChangesViewModel CreateVM(IList<TrackChanges> TrackChanges, MyBaseType entity)

You get no benefit from using generics here.

Assuming you want this method to perform similar operations on instances of several different classes, another option as others have already mentioned, is to get the method to accept a common base class that supports the operations you need.

If you're lucky, this base class already exists, or you can alter the type hierarchy and factor one in. If the classes are auto-generated, you can usually get them to implement an interface without altering their code directly (you certainly could with LINQ to SQL, not sure about the entity framework).

To do this, you create a partial class which implements the interface. Say you have a class Person which has code you can't touch, create your interface:

public interface ISupportCreateVm
{
    void SpecialOperationRequiredForCreateVM();
}

create a partial class in a new file like so:

public partial class Person : ISupportCreateVm
{
    void SpecialOperationRequiredForCreateVM()
    {
        // TODO: Implement me!
    }
}

You could then write your method as:

public static ShowTrackChangesViewModel CreateVM(IList<TrackChanges> TrackChanges, ISupportCreateVm entity)

and access the SpecialOperationRequiredForCreateVM() method on whatever you pass in.

The trouble is you'll have to do this for every class you want to pass to CreateVM, which is something I'm guessing you were looking at generics for in order to avoid in the first place! However, it certainly beats a massive block of if statements or a huge switch in terms of OO design.

Alex Humphrey