避免在通用函数中指定T类型

时间:2018-07-06 09:59:08

标签: c# function casting parent-child generic-function

我有这个通用扩展函数,该函数将具有特定父类型的对象转换为子类型(在此处找到代码:Unable to Cast from Parent Class to Child Class):

public static U ParentToChild<T, U>(this T parent) {
    if(!typeof(U).IsSubclassOf(typeof(T)))
        throw new Exception(typeof(U).Name + " isn't a subclass of " + typeof(T).Name);
    var serializedParent = JsonConvert.SerializeObject(parent);
    return JsonConvert.DeserializeObject<U>(serializedParent);
}

因此,当我调用此函数时,我需要同时指定Parent和Child类类型:

Child child = parent.ParentToChild<Parent, Child>();

有什么办法可以避免“父母”的准确性?

我想写这个:

Child child = parent.ParentToChild<Child>();

1 个答案:

答案 0 :(得分:0)

您可以将object设置为参数类型,并完全删除类型参数T

public static U ParentToChild<U>(this object parent) {
    // note how I used "parent.GetType()" instead of `typeof(T)`
    if (!typeof(U).IsSubclassOf(parent.GetType()))
        throw new Exception(typeof(U).Name + " isn't a subclass of " + parent.GetType().Name);
    var serializedParent = JsonConvert.SerializeObject(parent);
    return JsonConvert.DeserializeObject<U>(serializedParent);
}

顺便说一句,您的方法无论如何都没有充分利用泛型类型参数T。您可以将其用作U的约束,从而避免运行时检查:

public static U ParentToChild<T, U>(this T parent) where U : T {
    //                                            ^^^^^^^^^^^^^
    var serializedParent = JsonConvert.SerializeObject(parent);
    return JsonConvert.DeserializeObject<U>(serializedParent);
}

因此,如果您使用object作为参数,则会丢失此编译时类型检查。