Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting a generic class without specific type

I have the following generic class

public class Home<T> where T : Class
{
   public string GetClassType
   {
       get{ return T.ToString() }
   }
}

Now, I'm getting an Object X which I know for sure is Home:

public void DoSomething(object x)
{
    if(x is // Check if Home<>)
    {
        // I want to invoke GetClassType method of x  
        // but I don't know his generic type
        x as Home<?> // What should I use here?
    }
}

Can I even make a cast without specifying the generic type of the class?

like image 489
Pavel Tarno Avatar asked Jan 04 '11 14:01

Pavel Tarno


People also ask

Can you cast generic type Java?

The Java compiler won't let you cast a generic type across its type parameters because the target type, in general, is neither a subtype nor a supertype.

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 .

How do you restrict a generic class?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.


2 Answers

If you're sure the argument to DoSomething will be a Home<T>, why not make it a generic method?

public void DoSomething<T>(Home<T> home)
{
   ...
}

Of course, it would be even easier if DoSomething should logically be an instance method on Home<T>.

If you really want to stick with what you have, you could use reflection (untested):

public void DoSomething(object x)
{
    // null checks here.

    Type t = x.GetType();

    if (t.IsGenericType &&
          && t.GetGenericTypeDefinition() == typeof(Home<>))
    {
        string result = (string) t.GetProperty("GetClassType")
                                  .GetValue(x, null);

        Console.WriteLine(result);
    }

    else 
    {
        ... // do nothing / throw etc.
    }
}
like image 85
Ani Avatar answered Sep 20 '22 06:09

Ani


What if Home derived from a base class?

public class Home
{
    public virtual string GetClassType { get; }
}
public class Home<T> : Home
    where T : class
{
    public override string GetClassType
    {
        get{ return T.ToString() } 
    }
    ...
}

and then

public void DoSomething(object x)
{
    if(x is Home)
    {
        string ct = ((Home)x).GetClassType;
        ...
    }
}
like image 42
n8wrl Avatar answered Sep 19 '22 06:09

n8wrl