Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast object to a generic type

I haven't slept in a while so this is probably easier than I think it is.

I have a generic class that's more or less this:

public class Reference<T> where T : APIResource //<- APIResource is abstract btw
{
    private T _value = null;
    public T value
    { 
        get { return _value; }
    }
}

Elsewhere, in a custom serialize method, someone is passing in an object that is actually an instance of Reference<(something)>. I simply want to skip to the "value" property that every Reference<> object has, so I want to go:

string serialize(object o)
{
    return base.serialize( ((Reference<>) o).value );
}

Of course, life isn't that simple because as the compiler puts it:

using the generic type "Reference<T>" requires 1 type arguments

How can I do what I want to do?

like image 664
Alain Avatar asked May 28 '13 15:05

Alain


People also ask

Can you cast to a 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 you type cast an object?

An object can be converted from one data type to another using typecasting, also known as type conversion. It is employed in the programming language to guarantee that a function processes variables appropriately. Converting an integer to a string is an example of typecasting.

How do you cast an object to a specific class?

The cast() method of java. lang. Class class is used to cast the specified object to the object of this class. The method returns the object after casting in the form of an object.

How do you cast an object to a String in Java?

We can convert Object to String in java using toString() method of Object class or String. valueOf(object) method. You can convert any object to String in java whether it is user-defined class, StringBuilder, StringBuffer or anything else.


2 Answers

You can create a covariant generic interface with the property:

interface IReference<out T> where T : ApiResource {
    T Value { get; }
}

You can then cast IReference<Anything> to IReference<object> or IReference<ApiResource>.

like image 148
SLaks Avatar answered Oct 23 '22 18:10

SLaks


SLaks answer is perfect. I just want to extend it a little bit:

There are sometimes situations, where you can't substitute class with interface. Only in that cases you may want to use dynamic feature, so that you can call value property:

string serialize(object o)
{
    if(typeof(Reference<>) == o.GetType().GetGenericTypeDefinition())
        return base.serialize( ((dynamic)o).value );

    //in your case you will throw InvalidCastException
    throw new ArgumentException("not a Reference<>", "o"); 
}

This is just another options and I suggest to use it very carefully.

like image 29
Ilya Ivanov Avatar answered Oct 23 '22 17:10

Ilya Ivanov