简体   繁体   English

如何在通用方法中使用通用类型

[英]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? 例如,我可以在下面的LocalDataObjectEngine中调用cache.ResetCache()函数吗?

The error I'm getting is 'Type T cannot be used as a parameter' 我收到的错误是“类型T不能用作参数”

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>();
    }
}

}

I'm not sure what's going on unless there's something in your definition of IBrokeredDataObject . 我不确定发生了什么,除非您的IBrokeredDataObject定义中有IBrokeredDataObject What you've written looks right and compiles fine for me. 您写的内容对我来说不错,可以编译。

[Edited to match the edit in the OP] [根据OP中的编辑进行了编辑]

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? 为什么不在方法中使用T1而不是指定T应该像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: 在LocalDataObjectEngine_Cache中,您无需再次指定T,只需使用IBrokeredDataObject(如果您未实现该方法,然后右键单击接口名称以选择“实现接口”,它将如下所示:

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: 然后从上一课开始,只需指定您希望T成为的实际课再次调用它:

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

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

After removing the ..., the reference to IEngine, and providing an empty IBrokeredDataObject interface, your code compiles without any problems. 删除...之后,对IEngine的引用,并提供一个空的IBrokeredDataObject接口,您的代码可以毫无问题地进行编译。

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. 这样,我们就不需要修复“ ...”等或删除对我们没有声明的接口的引用。

Found it, Jon Skeet's reference to removing IEngine pointed me in the right direction, there was a 找到了它,乔恩·斯基特(Jon Skeet)关于删除IEngine的参考指出了正确的方向,

void ResetCache<T>() where T : IDataObject

on IEngine (IDataObject is a base if IBrokeredDataObject), that I changed to 在IEngine上(如果更改为IBrokeredDataObject,则IDataObject是基础)

void ResetCache<T>() where T : IBrokeredDataObject

Thanks all for tolerating my bug, +1 to you all 多谢大家容忍我的错误,向所有人+1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM