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

时间:2022-07-06 00:42:39

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'

我得到的错误是'Type 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>();
    }
}

}

4 个解决方案

#1


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.

除非你的IBrokeredDataObject定义中有什么东西,否则我不确定会发生什么。你所写的内容看起来是正确的并且对我来说很好。

[Edited to match the edit in the OP]

[编辑以匹配OP中的编辑]

#2


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

#3


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.

请提供一个简短但完整的示例,但不能编译。理想情况下,创建一个包含单个文件的新项目,将所有代码放在那里,并在显示相同错误时尽可能简单。然后剪切并粘贴到这里。这样我们就不需要修复“...”等或删除对我们没有声明的接口的引用。

#4


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上(IDataObject是IBrokeredDataObject的基础),我改为

void ResetCache<T>() where T : IBrokeredDataObject

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

感谢所有人容忍我的错误,给大家+1

#1


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.

除非你的IBrokeredDataObject定义中有什么东西,否则我不确定会发生什么。你所写的内容看起来是正确的并且对我来说很好。

[Edited to match the edit in the OP]

[编辑以匹配OP中的编辑]

#2


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

#3


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.

请提供一个简短但完整的示例,但不能编译。理想情况下,创建一个包含单个文件的新项目,将所有代码放在那里,并在显示相同错误时尽可能简单。然后剪切并粘贴到这里。这样我们就不需要修复“...”等或删除对我们没有声明的接口的引用。

#4


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上(IDataObject是IBrokeredDataObject的基础),我改为

void ResetCache<T>() where T : IBrokeredDataObject

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

感谢所有人容忍我的错误,给大家+1