C#转换为普通接口,基本类型 [英] C#: cast to generic interface with base type

查看:119
本文介绍了C#转换为普通接口,基本类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的code:

public interface IValidator<T>
{
   bool IsValid(T obj);
}

public class OrderValidator: IValidator<Order>
{
  // ...
}

public class BaseEntity
{
}

public class Order: BaseEntity
{
}

问题是,我不能做的:

The problem is that I can't do:

var validator = new OrderValidator();
// this line throws because type can't be converted
var baseValidator = (IValidator<BaseEntity>)validator;
// all this is because I need a list with IValidator<Order>, IValidator<BaseOrder>, etc.
IList<IValidator<BaseEntity>> allValidators = ...

我如何获得并存储IValidator&LT的所有实现的列表; T&GT;对碱基T - 说,BaseEntity?目前,我这样做,接受obj对象非通用IValidator但它不是好事,而不是类型安全的。

How do I get and store a list of all implementations of IValidator<T> for base T - say, BaseEntity? Currently I do non-generic IValidator that accepts "object obj" but it is not good and not type-safe.

有趣的东西是C#的允许以编译:

The funny stuff is that C# allows to compile:

var test = (IValidator<BaseEntity>)new OrderValidator();

但在运行时失败

   Unable to cast object of type 'OrderValidator' to type 'IValidator`1[Orders.Core.BaseEntity]'

这是同一个异常温莎给我(我想这两个温莎和手动类型查找,这个问题真的不涉及到这一点,只对接口铸件)。

This is the same exception that Windsor gives me (I tried both Windsor and manual types lookup, this issue is really not related to this, only to the interfaces casting).

由于Heinzi,现在我明白为什么我不能投 - 因为IValidator订单预计订单为一般类型。但我怎么回报为不同类型IValidator的名单?其原因是,BaseEntity接受其真正的类型和收集所有验证 - 适用于所有类型的GetType从()的对象。我很想有一个通用的GetValidators(),然后就可以进行操作。

Thanks to Heinzi, I see now why I can't cast - because IValidator for Order expects Order as generic type. But how do I return a list of IValidator for different types? The reason is that the BaseEntity takes its real type and gathers all validators - for all types from GetType() to the object. I'd really like to have a generic GetValidators() and then operate on it.

推荐答案

也许它可以帮助你,如果我解释为什么这个转换是被禁止的:假设你有以下功能

Maybe it helps you if I explain why this cast is forbidden: Assume that you have the following function

void myFunc(IValidator<BaseEntity> myValidator) {
    myValidator.IsValid(new BaseEntity());
}

这code将正确编译。不过,如果你传递了一个 OrderValidator 这个功能,你会得到一个运行时异常,因为 OrderValidator.IsValid 预计订单,而不是一个BaseEntity。如果你的施法被允许类型的安全将不再保留。

This code would compile correctly. Nevertheless, if you passed an OrderValidator to this function, you would get a run-time exception, because OrderValidator.IsValid expects an Order, not a BaseEntity. Type safety would no longer be maintained if your cast were allowed.

编辑:C#4允许<一个href=\"http://blogs.msdn.com/wriju/archive/2009/07/31/c-4-0-co-variance-and-contra-variance.aspx\">generic合作和逆变,但这不会在你的情况有所帮助,因为你使用T作为一个的输入的参数。因此,只有转换成一 IValidator&LT; SomeSubtypeOfOrder方式&gt; 可以在一个类型安全的方式来完成。

C# 4 allows for generic co- and contravariance, but this would not help in your case, since you use T as an input parameter. Thus, only casting to an IValidator<SomeSubtypeOfOrder> could be done in a type-safe way.

所以,要清楚,你不能施放 OrderValidator IValidator&LT; BaseEntity&GT; ,因为你的OrderValidator只能验证订单,而不是各种BaseEntities的。然而,什么是可以预期的将一个 IValidator&LT; BaseEntity方式&gt;

So, to be clear, you cannot cast OrderValidator to IValidator<BaseEntity> because your OrderValidator can only validate orders, not all kinds of BaseEntities. This, however, is what would be expected of an IValidator<BaseEntity>.

这篇关于C#转换为普通接口,基本类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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