【问题标题】:Avoid having to specify T type in a generic function避免在泛型函数中指定 T 类型
【发布时间】:2018-07-06 09:59:07
【问题描述】:

我有这个通用扩展函数,它将具有特定父类型的对象转换为子类型(在此处找到代码: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);
}

所以当我调用这个函数时,我需要同时指定父类和子类类型:

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

有什么办法可以避免'父'精度?

我想写这个:

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

【问题讨论】:

  • 不,没有办法做到这一点。

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


【解决方案1】:

可以将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 作为参数,您将失去此编译时类型检查。

【讨论】:

  • 谢谢!我总是忘记 c# 如何使用“where”关键字变得简单
猜你喜欢
  • 2015-12-09
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 2020-12-27
相关资源
最近更新 更多