简体   繁体   English

.NET Core Cast与具有实现接口的类型的通用类型参数的接口

[英].NET Core Cast to interface with generic type parameter of type which implements interface

In .NET Core C# I' trying something like this: 在.NET Core C#中,我正在尝试如下操作:

(IInterface<IParameter>)instance

Where instance is new Implementation<Parameter>() 实例是new Implementation<Parameter>()

And Implementation : IInterface & Parameter : IParameter Implementation : IInterfaceParameter : IParameter

The issue is with the casting of the generic parameter. 问题在于泛型参数的强制转换。 When I provide Parameter instead of IParameter it works but at compile time there is no way to know which type that implements IParameter will be used. 当我提供Parameter而不是IParameter它可以工作,但在编译时无法IParameter将使用实现IParameter类型。 All of these objects will be created via reflection. 所有这些对象都将通过反射创建。

So is there any way this cast works? 那么这个演员有什么办法吗? Or some other way to implement this like providing no generic type parameter like you can with typeof . 或其他实现方式,例如不提供泛型类型参数,就像可以使用typeof

EDIT Thanks to Ziriax 编辑感谢Ziriax

A Fully Working Example: 一个完整的示例:

interface IInterface
{
    void Run(TInput input);
}

abstract class AbstractClass<TInput> : IInterface
    where TInput : IParameter
{
    public abstract void Execute(TInput input);

    public void Run(IParameter input)
    {
        Execute((TInput)input);
    }
}

interface IParameter {}

class Implementation : AbstractClass<Parameter>
{
    public void Run(Parameter input)
    {
    }
}

class Parameter : IParameter {}

class Program
{
    static void Main()
    {
        object instance = new Implementation();
        var castInstance = (IInterface) instance;
        castInstance.Run(new Parameter());
    }
}

As you have it now, this cannot work. 就像您现在拥有的那样,这是行不通的。 Your Implementation class implements IInterface<Parameter> , so its Run method only accepts a parameter of the concrete Parameter type, whereas the IInterface<IParameter> requires that its Run method accepts an instance of any type that implements IParameter . 您的Implementation类实现IInterface<Parameter> ,因此其Run方法仅接受具体Parameter类型的Parameter ,而IInterface<IParameter>要求其Run方法接受任何实现IParameter类型的实例。

If the type of cast you're trying to do were allowed, I could define a different class that implements IParameter , eg: 如果允许您尝试执行的IParameter ,则可以定义一个实现IParameter的其他类,例如:

public class DifferentParameter : IParameter { ... }

And then do: 然后执行:

castInstance.Run(new DifferentParameter());

But your Implementation 's Run method can't take DifferentParameter ! 但是您ImplementationRun方法不能采用DifferentParameter

.NET therefore prevents you from performing the cast itself. 因此,.NET阻止您执行自身的转换。

There are situations in which this kind of cast is allowed - if your interface were instead to be defined as: 在某些情况下,允许这种类型的转换-如果将您的接口定义为:

interface IInterface<out TOutput>
    where TOutput : IResult
{
    TOutput Run();
}

By making the generic parameter out , it makes the interface covariant . 通过将泛型参数out ,可以使接口协变 This restricts the use of the type parameter as the result of method calls, but for covariant interfaces, casts like yours are allowed. 这限制了类型参数作为方法调用的结果的使用,但是对于协变接口,允许像您一样进行强制类型转换。

You can find plenty of documentation on both covariance and contravariance in the .NET documentation . 您可以在.NET文档中找到大量有关协方差和协方差的文档

Why don't you add a non-generic interface too: 为什么也不要添加非通用接口:

interface IInterface { void Run(IParameter input); }

And then let your generic interface extend this non-generic one. 然后让您的通用接口扩展此非通用接口。

Obviously your implementations should cast the IParameter , someone needs to cast it... You could make an abstract base class that does this for you, so not every implementation has to do this. 显然,您的实现应该IParameter ,有人需要对其进行转换...您可以创建一个抽象基类来为您执行此操作,因此并非每个实现都必须执行此操作。

You might also be interested in the double dispatch pattern, although I'm not sure this will work in your case. 您可能还对双调度模式感兴趣,尽管我不确定这是否适用于您的情况。

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

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