类型参数 - 从类型 T 获取具体类型:IMyInterface

发布于 2024-11-25 12:54:09 字数 1982 浏览 0 评论 0原文

假设我有一个 List...

我有三个实现 IMyInterface 的类:MyClass1MyClass2 ,和 MyClass3

我有一个只读字典:

private static readonly Dictionary<Type, Type> DeclarationTypes = new Dictionary<Type, Type>
{
    { typeof(MyClass1), typeof(FunnyClass1) },
    { typeof(MyClass2), typeof(FunnyClass2) },
    { typeof(MyClass3), typeof(FunnyClass3) },
};

我有另一个接口,IFunnyInteface;其中 T : IMyInterface

我有一个方法:

public static IFunnyInterface<T> ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
    if (DeclarationTypes.ContainsKey(node.GetType())) {
        IFunnyInterface<T> otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
        return otherClassInstance;
    }
    return null;
}

我试图调用unnyClasses的构造函数并插入我的MyClass对象作为参数。我不想知道它是哪个对象:我只想用 MyClass 作为参数实例化一些FunnyClass。

当我调用 ConvertToFunnyClass 时会发生什么,T 的类型为 IMyInterface,当我尝试将其转换为 FunnyInterface 时,它说我例如,无法将 FunnyClass1 转换为 FunnyInterface

我当前的解决方法(不是一个漂亮的方法)是这样的

public static dynamic ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
    if (DeclarationTypes.ContainsKey(node.GetType())) {
        var otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
        return otherClassInstance;
    }
    return null;
}

:不喜欢它,因为返回类型是动态的,所以当我从其他地方访问它时,我不知道它是什么类型,并且我失去了智能感知之类的东西。我也不知道对性能有何影响。

有什么线索吗?

提前致谢!

解决方案

由于我使用的是 C# 4.0,我可以使用协方差(仅输出位置)来停止转换错误,因此我将 IFunnyInterface 更改为

IFunnyInteface<out T> where T : IMyInterface

感谢大家的回复。

Suppose I have a List<IMyInterface>...

I have three classes which implement IMyInterface: MyClass1, MyClass2, and MyClass3

I have a readonly Dictionary:

private static readonly Dictionary<Type, Type> DeclarationTypes = new Dictionary<Type, Type>
{
    { typeof(MyClass1), typeof(FunnyClass1) },
    { typeof(MyClass2), typeof(FunnyClass2) },
    { typeof(MyClass3), typeof(FunnyClass3) },
};

I have another interface, IFunnyInteface<T> where T : IMyInterface

I have a method:

public static IFunnyInterface<T> ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
    if (DeclarationTypes.ContainsKey(node.GetType())) {
        IFunnyInterface<T> otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
        return otherClassInstance;
    }
    return null;
}

I'm trying to call the constructor of FunnyClasses and insert as parameter my MyClass object. I don't want to know which object it is: I just want to instantiate some FunnyClass with MyClass as a parameter.

What happens when I call ConvertToFunnyClass, T is of type IMyInterface, and when I try to cast it to FunnyInterface<T>, it says I can't convert FunnyClass1, for instance, to FunnyInterface<IMyInterface>

My current workaround (not a beautiful one), is this:

public static dynamic ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
    if (DeclarationTypes.ContainsKey(node.GetType())) {
        var otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
        return otherClassInstance;
    }
    return null;
}

And I don't like it because the return type is dynamic, so when I access it from somewhere else, I have no idea what type it is, and I lose intellisense, and stuff. I don't know about any performance implications either.

Any clues?

Thanks in Advance!

Resolution

As I'm using C# 4.0, I could stop casting errors using covariance (output positions only), and so I changed my IFunnyInterface to

IFunnyInteface<out T> where T : IMyInterface

Thank you all for the replies.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温馨耳语 2024-12-02 12:54:09

本质上,您的问题是您试图将 FunnyInterface 转换为 FunnyInterface。正如多次提到的(一个例子是 此处,更多信息此处),这在大多数情况下无效。仅在 .NET 4 中,当泛型类型为接口或委托,并且类型参数已使用 inout 显式声明为变体时,才能执行此转换。

FunnyInterface 实际上是一个接口吗?

Essentially, your problem is that you are trying to convert FunnyInterface<T> to FunnyInterface<IMyInterface>. As has been mentioned several times (one example is here, more information here), this is not valid in most circumstances. Only in .NET 4, when the generic type is an interface or delegate, and the type parameter has been explicitly declared as variant with in or out, can you perform this conversion.

Is FunnyInterface actually an interface?

゛清羽墨安 2024-12-02 12:54:09

thecoop 的答案准确地向您指出了为什么您不能这样做。

解决该问题的更清晰的解决方案(除了使用动态之外)将是一个基本的非泛型接口:

public interface IFunnyInterfaceBase
{
}

public interface IFunnyInteface<T> : IFunnyInterfaceBase 
    where T : IMyInterface
{
}

并且您需要将该代码中使用的方法签名从 IFunnyInteface 移动到 IFunnyInterfaceBase。

这样你就可以写这样的东西:

MyClass2 c2 = new MyClass2();
IFunnyInterfaceBase funnyInstance = c2.ConvertToFunnyClass();

你说你在代码中得到的异常不是由于扩展方法签名本身(该方法很好)..它是由你的左值的类型(类型用于存储其返回值的变量)!

显然,只有当您可以修改 IFunnyInterface 源代码时,此解决方案才适用!

thecoop answer points you exactly to why you can't do it.

A cleaner solution to the problem (besides using dynamic) would be a base non-Generics Interface:

public interface IFunnyInterfaceBase
{
}

public interface IFunnyInteface<T> : IFunnyInterfaceBase 
    where T : IMyInterface
{
}

And you need to move methods signature you use in that code from IFunnyInteface to IFunnyInterfaceBase.

This way you would be able to write something like this:

MyClass2 c2 = new MyClass2();
IFunnyInterfaceBase funnyInstance = c2.ConvertToFunnyClass();

The Exception you said you got in your code is not due to the extension method signature itself (the method is fine)..it is originated by the type of your lvalue (the type of the variable you use to store its return value)!

Obviously this solution applies only if you can modify IFunnyInterface source code!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文