Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting a non-generic type to a generic one

Tags:

c#

generics

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?

like image 925
John Sheehan Avatar asked Mar 29 '10 04:03

John Sheehan


People also ask

Can a non-generic class have a generic method?

Yes, you can define a generic method in a non-generic class in Java.

Can a non-generic class inherit a generic class?

Yes, in this case, inheritance is a better solution than composition as you have it, because a StackInteger is a Stack .

Can you have a generic method in a non-generic class C#?

In C# and similar languages, all methods belong to classes. Some of these classes are generic, some are just simple, ordinary classes. We can have generic methods in both generic types, and in non-generic types.

What is unbound generic type?

An unbound type refers to the entity declared by a type declaration. An unbound generic type is not itself a type, and cannot be used as the type of a variable, argument or return value, or as a base type. The only construct in which an unbound generic type can be referenced is the typeof expression (§11.7. 16).


1 Answers

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.

like image 100
Anthony Pegram Avatar answered Sep 30 '22 06:09

Anthony Pegram