在运行时动态定义泛型类型T.

时间:2013-03-09 00:45:01

标签: c# fluentvalidation

1。 我有一个函数DoSomeService与对象响应作为参数。响应是不同的类,内部代码决定在运行时动态使用哪一个。

2。 我有一个通用的Fluent Validator< T>它接受响应类的类型,然后验证它。

现在,我可以逐个进行类型检查:

public override void DoSomeService(object response) {
    object validator = null;
    if (response.GetType()==typeof(TypeA_Response)) validator= new Validator<TypeA_Response>();
    if (response.GetType()==typeof(TypeB_Response)) validator= new Validator<TypeB_Response>();
    if (response.GetType()==typeof(TypeC_Response)) validator= new Validator<TypeC_Response>();
    //......
    if (response.GetType()==typeof(TypeX_Response)) validator= new Validator<TypeX_Response>();
        if (validator.IsValid) {
        //do more stuff ...
    }
}

但这并不好,尤其是当我有很多回复时。我想要一些简短而通用的东西。

//response could be TypeA_Response, TypeB_Response, TypeX_Response
public override void DoSomeService(object response) {
    var validator = new Validator<T>();
    if (validator.IsValid) {
        //do more stuff ...
    }
}

当然,这不起作用,因为我需要为Fluent Validator定义T.如何检测“对象响应”是什么类型并在运行时将其填充到T中?

或者我如何避免这样做,并为我的验证器提供更好的结构&lt; T&gt;?

注意,我无法更改基本Service类和DoSomeService函数签名,它是来自第三方包的覆盖函数。

2 个答案:

答案 0 :(得分:2)

如果你真的希望这是动态的,最好的方法是使用反射

void DoSomething(object response)
{
    var type = typeof(Validator<>);
    var boundType = type.MakeGenericType(response.GetType());
    var validator = Activator.CreateInstance(boundType);
}

即使使用此解决方案,您仍然无法在此上下文中使用Validator<T>,因为您仍然不知道T是什么。必须静态定义T才能以这种方式使用。您需要将Validator<T>拆分为通用和非泛型基类型,并在DoSomething方法中使用非泛型类型

Validator valdiator = Activator.CreateInstance(boundType);

答案 1 :(得分:1)

这不是真正的泛型。相反,您将拥有一个带有虚拟方法的基类来进行验证,或者要求具体类型实现一个具有验证方法的特定接口。