Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Method gets parameter type from superclass

I have a problem with a typed method in C#. I want to invoke a inherited method of an object. This method invokes a static method with "this" as parameter. The parameter of the static method is generic. I now want the generic type of this parameter to be the type of the first object. But the parameter has always the type of the abstract class.

Here is the example:

abstract class AbstractClass
{
    bool update()
    {
        Connection.Update(this);
    }
}

class Entity : AbstractClass
{
}

class Connection
{
    public static void Update<T>(T obj)
    {
        someMethod<T>()
    }
}

If I try to do:

Entity foo = new Entity();
foo.update();

Connection.Update will look in the Debugger like this:

public static void Update<AbstractClass>(AbstractClass obj)
{
    someMethod<AbstractClass>()
}

But I want this:

public static void Update<Entity>(Entity obj)
{
    someMethod<Entity>()
}

Is there any possibility to something like

someMethod<typeof(obj)>()

or anything else to solve my problem?

like image 423
Jan S Avatar asked Jan 31 '14 13:01

Jan S


People also ask

Can generics take multiple type parameters?

A Generic class can have muliple type parameters.

How do you provide the Parametrized type for a generic?

In order to use a generic type we must provide one type argument per type parameter that was declared for the generic type. The type argument list is a comma separated list that is delimited by angle brackets and follows the type name. The result is a so-called parameterized type.

Can generic class inherit?

An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.

Can we use generic type parameter in static class members?

Using generics, type parameters are not allowed to be static. As static variable is shared among object so compiler can not determine which type to used.


2 Answers

You can declare the base class as a generic one, here is the example:

abstract class AbstractClass<T>
{
    bool update()
    {
        Connection.Update<T>(this as T);
    }
}

class Entity : AbstractClass<Entity>
{
}

class Connection
{
    public static void Update<T>(T obj)
    {
        someMethod<T>()
    }
}
like image 183
Alexandr Mihalciuc Avatar answered Oct 23 '22 11:10

Alexandr Mihalciuc


Compiler tries to infer the type of T parameter, in the base class it does not have information to infer Entity type. So you should provide information of the child type while you want to call the Update function.@Alexandr answer is a good one just an improvement adding type constraint to T type parameter to restrict it be a child of AbstractClass

abstract class AbstractClass<T>
where T: AbstractClass<T> //restrict T as a child of AbstractClass<T>
{
    bool update()
    {
        Connection.Update<T>(this as T);
    }
}

class Entity : AbstractClass<Entity>
{
}

class Connection
{
    public static void Update<T>(T obj)
    {
        someMethod<T>()
    }
}
like image 31
Mojtaba Avatar answered Oct 23 '22 10:10

Mojtaba