简体   繁体   中英

Casting a non-generic type to a generic one

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?

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.

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> .

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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM