【问题标题】:.NET Core Cast to interface with generic type parameter of type which implements interface.NET Core Cast 与实现接口的类型的泛型类型参数接口
【发布时间】:2019-03-22 13:04:54
【问题描述】:

在 .NET Core C# 中 我正在尝试这样的事情:

(IInterface<IParameter>)instance

实例在哪里new Implementation&lt;Parameter&gt;()

还有Implementation : IInterface & Parameter : IParameter

问题在于泛型参数的转换。当我提供Parameter 而不是IParameter 时,它可以工作,但在编译时无法知道将使用哪个实现IParameter 的类型。所有这些对象都将通过反射创建。

那么这个演员有什么办法吗?或者其他一些实现这一点的方法,比如像 typeof 那样不提供泛型类型参数。

编辑感谢 Ziriax

一个完整的例子:

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

【问题讨论】:

  • 如果您使用out,它会解决您的问题,但函数除外(注释掉函数和代码运行)。我还在研究这个功能
  • 感谢您的回复!我忘了添加 in 修饰符。由于TInput 被用作参数,我不能使用out 协变,或者我可以吗?

标签: c# .net generics reflection interface


【解决方案1】:

你为什么不也添加一个非通用接口:

interface IInterface { void Run(IParameter input); }

然后让你的通用接口扩展这个非通用接口。

显然你的实现应该转换IParameter,有人需要转换它...你可以创建一个抽象基类来为你做这件事,所以不是每个实现都必须这样做。

您可能还对双重调度模式感兴趣,尽管我不确定这是否适用于您的情况。

【讨论】:

  • 是的,你说的太对了!谢谢。非泛型接口和泛型抽象类完美地工作。我将很快发布完整的示例。
【解决方案2】:

正如你现在所拥有的,这是行不通的。你的Implementation 类实现了IInterface&lt;Parameter&gt;,所以它的Run 方法只接受一个具体的Parameter 类型的参数,而IInterface&lt;IParameter&gt; 要求它的Run 方法接受一个any em> 实现IParameter 的类型。

如果允许您尝试执行的转换类型,我可以定义一个实现 IParameter 的不同类,例如:

public class DifferentParameter : IParameter { ... }

然后做:

castInstance.Run(new DifferentParameter());

但是你ImplementationRun方法不能取DifferentParameter

.NET 因此会阻止您自己执行转换。

在某些情况下允许这种类型的转换 - 如果您的接口被定义为:

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

通过使泛型参数out,它使接口协变。这限制了类型参数作为方法调用的结果的使用,但对于协变接口,像你这样的转换是允许的。

您可以在.NET documentation 中找到大量关于协变和逆变的文档。

【讨论】:

  • 我需要保持不变的主要是Run 方法它需要将特定类型作为参数,我不想在函数中强制转换参数。同样在 Main 方法的编译时,我不可能知道特定类型可以/将会是什么。你能想出什么方法来实现这一点吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 2018-09-15
相关资源
最近更新 更多