tags:

views:

132

answers:

3

I've got this class:

class Foo { 
    public string Name { get; set; }
}

And this class

class Foo<T> : Foo {
    public T Data { get; set; }
}

Here's what I want to do:

public Foo<T> GetSome() {
    Foo foo = GetFoo();

    Foo<T> foot = (Foo<T>)foo;
    foot.Data = GetData<T>();
    return foot;
}

What's the easiest way to convert Foo to Foo<T>? I can't cast directly InvalidCastException) and I don't want to copy each property manually (in my actual use case, there's more than one property) if I don't have to. Is a user-defined type conversion the way to go?

+1  A: 

If you are getting an InvalidCastException, the Foo type returned by GetFoo() is not Foo<T>. You will need to either pass T or typeof(T) to that function so it can return an instance of Foo<T>.

leppie
The cast exception is on the `Foo<T> foot = (Foo<T>)foo;` line, not the return from GetFoo(); That's just a stub to demonstrate the structure.
John Sheehan
My point still stands. Look where the problem comes from, not where it happens.
leppie
It doesn't answer the bigger question though. I already know that cast isn't possible, it's just a demonstration of my intent.
John Sheehan
@John Sheehan: Then see my 2nd sentence in my answer. There are other options too, like passing a new instance of `Foo<T>` into the `GetFoo` method to populate it. If that is not the case, please clarify your question. :)
leppie
Or make `GetFoo` generic: `Foo<T> GetFoo<T>()`
280Z28
@280Z28: You may not want that :) `void PopulateFoo(Foo f)` would be better.
leppie
+2  A: 

You can create an explicit conversion from Foo within Foo<T>.

class Program
{
    static void Main()
    {
        Foo foo = new Foo();
        foo.Name = "Blah";
        Foo<int> newfoo = (Foo<int>)foo;
        Console.WriteLine(newfoo.Name);
        Console.Read();
    }
}

class Foo
{
    public string Name { get; set; }
    public object Data { get; set; }
}

class Foo<T>
{
    public string Name { get; set; }
    public T Data { get; set; }
    public static explicit operator Foo<T>(Foo foo)
    {
        Foo<T> newfoo = new Foo<T>();
        newfoo.Name = foo.Name;
        return newfoo;
    }
}

Edit: This only works without inheritance. It appears you are not able to do a user-defined conversion from a base to a derived class. See comments from Mads Torgersen here http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/14cf27cf-b185-43d6-90db-734d2ca3c8d4/ :

We have taken the liberty of predefining conversions (casts) between base classes and derived classes, and to make the semantics of the language predictable we don't allow you to mess with it.

It looks like you may be stuck with defining a method to turn a Foo into a Foo<T>. That, or drop the inheritance. Neither solution sounds particularly ideal.

Anthony Pegram
OK that's what I thought. Just looking for validation :) Thanks
John Sheehan
This doesn't work: "user-defined conversions to or from a base class are not allowed"
John Sheehan
@John Sheehan: His example will work, but not if you have inheritance.
leppie
That's interesting, I did not notice the inheritance. My example works without it. Back to the drawing board.
Anthony Pegram
A Good Thought... I wasn't aware of this... Thanks for keeping me learning (+1)
The King
A: 

Use copy constructors. Foo implements:

class Foo {
     Foo(Foo copy) { ... }
}

while Foo shall be constructed using the following:

class Bar<T> : Foo {
      Bar(Foo copy) : base(copy) { ... }
}

...Yes. You need to copy member by member, and this should be done in "copy constructor".

Luca