gpt4 book ai didi

C#:转换为具有基类型的泛型接口(interface)

转载 作者:可可西里 更新时间:2023-11-01 08:42:18 25 4
gpt4 key购买 nike

代码如下:

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

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

public class BaseEntity
{
}

public class Order: BaseEntity
{
}

问题是我做不到:

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 = ...

如何获取和存储基础 T(例如 BaseEntity)的 IValidator 的所有实现的列表?目前我做的是接受“object obj”的非通用 IValidator,但它不好而且类型不安全。

有趣的是 C# 允许编译:

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

但在运行时失败

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

这与 Windsor 给我的异常相同(我尝试了 Windsor 和手动类型查找,这个问题实际上与此无关,仅与接口(interface)转换有关)。

感谢 Heinzi,我现在明白了为什么我不能转换 - 因为 Order 的 IValidator 期望 Order 作为泛型类型。但是如何返回不同类型的 IValidator 列表呢?原因是 BaseEntity 采用其真实类型并收集所有验证器 - 对于从 GetType() 到对象的所有类型。我真的很想拥有一个通用的 GetValidators() 然后对其进行操作。

最佳答案

如果我解释一下为什么禁止强制转换,也许它会对您有所帮助:假设您具有以下功能

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

这段代码可以正确编译。尽管如此,如果你通过了 OrderValidator对于这个函数,你会得到一个运行时异常,因为 OrderValidator.IsValid需要一个订单,而不是一个 BaseEntity。如果您的转换被允许,类型安全将不再得到维护。

编辑:C# 4 允许 generic co- and contravariance ,但这对您的情况没有帮助,因为您将 T 用作输入参数。因此,只能转换为 IValidator<SomeSubtypeOfOrder>可以以类型安全的方式完成。

所以,明确地说,你不能投OrderValidatorIValidator<BaseEntity>因为你的 OrderValidator 只能验证订单,不能验证各种 BaseEntities。然而,这是对 IValidator<BaseEntity> 的期望。 .

关于C#:转换为具有基类型的泛型接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1749886/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com