如何使用泛型类型时,正确蒙上了类的抽象类? [英] How to correctly cast a class to an abstract class when using type generics?

查看:163
本文介绍了如何使用泛型类型时,正确蒙上了类的抽象类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类

public abstract class BaseViewPresenter { }
public abstract class BaseView<T> : UserControl
    where T : BaseViewPresenter { }

public class LoginPresenter : BaseViewPresenter { }
public partial class LoginView : BaseView<LoginPresenter> {  }

我有一个看起来像这样的方法(简体)

I have a method that looks like this (simplified)

public BaseView<BaseViewPresenter> Resolve(BaseViewPresenter model)
{
    var type = model.GetType();
    var viewType = _dataTemplates[type];

    // Correctly creates BaseView object
    var control = Activator.CreateInstance(viewType);

    // Fails to cast as BaseView<BaseViewPresenter> so returns null
    return control as BaseView<BaseViewPresenter>;
}

在我使用的登录presenter的情况下调用此

When I call this using an instances of LoginPresenter

var login = new LoginPresenter();
var ctl = Resolve(login);

Activator.CreateInstance(viewType)正确解析到我的 LoginView ,但<$的新实例C $ C>控制作为基本视点&LT;基本视点presenter&GT; 不能正确地做投这样的回报

The line Activator.CreateInstance(viewType) correctly resolves into a new instances of my LoginView, however control as BaseView<BaseViewPresenter> can't do the cast correctly so returns null.

有没有办法正确地投控制基本视点&LT;基本视点presenter&GT; ,而无需使用特定的泛型类型?

Is there a way to correctly cast the control into BaseView<BaseViewPresenter> without using specific type generics?

由于 LoginView 基本视点&LT继承;登录presenter&GT; 登录presenter 基本视点presenter 继承,我会假设有一种方法来转换 LoginView 基本视点&LT;基本视点presenter&GT;

Since LoginView inherits from BaseView<LoginPresenter>, and LoginPresenter inherits from BaseViewPresenter, I would assume there's a way to convert LoginView to BaseView<BaseViewPresenter>.

我坚持使用.net 3.5

I am stuck with using .Net 3.5

推荐答案

这是一个很常见的问题。让我们重命名你的类型:

This is a very frequently asked question. Let's rename your types:

abstract class Fruit { }                    // was BaseViewPresenter
abstract class FruitBowl<T> where T : Fruit // was BaseView
class Apple : Fruit { }                     // was LoginPresenter
class BowlOfApples : FruitBowl<Apple> {  }  // was LoginView

您现在的问题是:

我有一个 BowlOfApples ,它继承了 FruitBowl&LT;苹果&GT; 。为什么我不能用它作为 FruitBowl&LT;水果&GT; ?苹果是一种水果,这样一碗苹果是一碗水果。

I have a BowlOfApples, which inherits from FruitBowl<Apple>. Why can I not use it as a FruitBowl<Fruit>? An apple is a fruit, so a bowl of apples is a bowl of fruit.

没有,事实并非如此。 您可以把香蕉一碗水果,但你不能把一个香蕉一碗苹果,因此一碗苹果是不是一碗水果。 (并且通过类似的说法,一碗水果是不是一碗苹果无论是。)由于操作就可以合法地在两种类型的执行都的不同的的,他们不能的兼容

No, it isn't. You can put a banana in a bowl of fruit, but you can't put a banana in a bowl of apples, and therefore a bowl of apples is not a bowl of fruit. (And by similar argument, a bowl of fruit is not a bowl of apples either.) Since the operations you can legally perform on the two types are different, they cannot be compatible.

下面是计算器传说乔恩斯基特的照片展示了这样一个事实:

Here is a photo of StackOverflow legend Jon Skeet demonstrating this fact:

你想要的功能称为通用逆变的,它仅支持的接口委托类型的编译器可以证明方差是安全的,并且当改变类型是引用类型。例如,您可以使用的IEnumerable&LT;苹果&GT; 的IEnumerable℃的范围内;水果GT; 是必要的,因为编译器可以验证有没有办法,你可以把一个香蕉成水果序列。

The feature you want is called generic contravariance, and it is supported only on interfaces and delegate types when the compiler can prove that the variance is safe, and when the varying type is a reference type. For example, you can use an IEnumerable<Apple> in a context where IEnumerable<Fruit> is needed because the compiler can verify that there is no way that you can put a Banana into a sequence of fruit.

请在本网站或在网络上的C#协变和逆变搜索,你会发现有关此功能工作的更多详情,请。尤其是我一系列关于如何文章中,我们设计并实现了在C#中此功能4由此开始:<一href="http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx">http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx

Do a search on "C# covariance and contravariance" on this site or on the web and you'll find many more details about how this feature works. In particular, my series of articles on how we designed and implemented this feature in C# 4 starts here: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx

这篇关于如何使用泛型类型时,正确蒙上了类的抽象类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆