johnc
johnc

Reputation: 40223

How to use a generic type in generic method

EDITED to show real example

How can I call a generic function from a generic type passed to a function? This seems like it should be intuitive, but I can't seem to get it to work.

For example, can I call the cache.ResetCache() function in LocalDataObjectEngine below?

The error I'm getting is 'Type T cannot be used as a parameter'

public interface ISimpleCache<T1>
{    
    ...
    void ResetCache<T>() where T : T1;
}

internal class LocalDataObjectEngine_Cache : ISimpleCache<IBrokeredDataObject>
{
    ISimpleCache<IBrokeredDataObject> _cache;

    ...

    public void ResetCache<T>() where T : IBrokeredDataObject
    {
        //logic here
    }

    ...
}

public partial class LocalDataObjectEngine : IEngine
{
    ISimpleCache<IBrokeredDataObject> _cache  = new LocalDataObjectEngine_Cache();

    public void ResetCache<T>() where T : IBrokeredDataObject
    {
        _cache.ResetCache<T>();
    }
}

}

Upvotes: 2

Views: 3159

Answers (4)

johnc
johnc

Reputation: 40223

Found it, Jon Skeet's reference to removing IEngine pointed me in the right direction, there was a

void ResetCache<T>() where T : IDataObject

on IEngine (IDataObject is a base if IBrokeredDataObject), that I changed to

void ResetCache<T>() where T : IBrokeredDataObject

Thanks all for tolerating my bug, +1 to you all

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500415

After removing the ..., the reference to IEngine, and providing an empty IBrokeredDataObject interface, your code compiles without any problems.

Please provide a short but complete example which doesn't compile. Ideally, create a new project with a single file in, put all your code in there, and make it as simple as possible while showing the same error. Then just cut and paste into here. That way we don't need to fix up "..." etc or remove references to interfaces which we don't have declarations for.

Upvotes: 1

mbillard
mbillard

Reputation: 38842

First of all, why do you need to specify a generic type in your methods? The class already specifies the generic type, you'll have access to it in your methods:

public interface ISimpleCache<T1>
{    
    ...
    void ResetCache();
}

which makes the class that implements the interface much simpler:

internal class LocalDataObjectEngine_Cache : ISimpleCache<IBrokeredDataObject>
{
    ISimpleCache<IBrokeredDataObject> _cache;

    ...

    public void ResetCache();
    {
        //logic here with access to IBrokeredDataObject if needed
    }

    ...
}

the same goes for the last method, just call

_cache.ResetCache();

however, if you really need to specify the generic type in the methods for some reason, do as below


Let's start:

Why don't you use T1 in the method instead of specifying T should be like T1?

public interface ISimpleCache<T1>
{    
    ...
    void ResetCache<T1>();
}

In your LocalDataObjectEngine_Cache, you don't have to specify T again, just use IBrokeredDataObject (if you don't implement the method, and right-click on the interface name to choose "Implement interface", it will write it as below:

internal class LocalDataObjectEngine_Cache : ISimpleCache<IBrokeredDataObject>
{
    ISimpleCache<IBrokeredDataObject> _cache;

    ...

    public void ResetCache<IBrokeredDataObject>();
    {
        //logic here
    }

    ...
}

Then from your last class, just call it again by specifying the actual class you want T to be:

public partial class LocalDataObjectEngine : IEngine
{
    ISimpleCache<IBrokeredDataObject> _cache  = new LocalDataObjectEngine_Cache();

    public void ResetCache<IBrokeredDataObject>()
    {
        _cache.ResetCache<IBrokeredDataObject>();
    }
}

Upvotes: 1

lc.
lc.

Reputation: 116458

I'm not sure what's going on unless there's something in your definition of IBrokeredDataObject. What you've written looks right and compiles fine for me.

[Edited to match the edit in the OP]

Upvotes: 1

Related Questions