How to call a method on a generic type from inside the generic class?

60 views Asked by At

I have the following classes:

public abstract class TableStorageItem
{
    public TableStorageItem() { }
}
public abstract class TableStorage<T> where T : TableStorageItem, new()
{
    public async Task CheckInitializeAsync(CancellationToken cancellationToken = default)
    {
     ...
    }
}
public class TableStorageCleanerTask<T, U>
    where T : TableStorage<U>
    where U : TableStorageItem, new()
{
    public TableStorageCleanerTask() { }

    public async Task InitializeAsync(CancellationToken cancellationToken = default)
    {
        await T.CheckInitializeAsync(cancellationToken)
    }
}

I would like to call CheckInitializeAsync from inside InitializeAsync but I have this CS0704 compiler error:

Cannot do non-virtual member in T because it is a type parameter.

I am sure that there is a way to do this but I can't figure it out.

2

There are 2 answers

0
jepozdemir On BEST ANSWER

you are trying to call instance method like static method. You have to declare your function as following that accepts a TableStorage instance or you may create a new instance then call CheckInitializeAsync() function in InitializeAsync():

public class TableStorageCleanerTask<T, U>
where T : TableStorage<U>
where U : TableStorageItem, new()
{
    public TableStorageCleanerTask() { }

    public async Task InitializeAsync(T storage, CancellationToken cancellationToken = default)
    {
        await storage.CheckInitializeAsync(cancellationToken);
    }
}
0
JohnLBevan On

Per @Sweeper's comment, the CheckInitializeAsync method is not static, so cannot be called against the class; only against an object instantiated from that class.

public class TableStorageCleanerTask<T, U>
    where T : TableStorage<U>
    where U : TableStorageItem, new()
{
    private T tableStorage;
    public TableStorageCleanerTask(T tableStorage)
    {
        this.tableStorage = tableStorage;
    }

    public async Task InitializeAsync(CancellationToken cancellationToken = default)
    {
        await tableStorage.CheckInitializeAsync(cancellationToken)
    }
}