Избегайте необходимости указывать тип T в обобщенной функции - PullRequest
0 голосов
/ 06 июля 2018

У меня есть эта универсальная расширяющая функция, которая приводит объект с определенным родительским типом к дочернему типу (нашел код здесь: Невозможно преобразовать родительский класс в дочерний класс ):

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>();

Есть ли способ избежать точности 'Parent'?

Я хотел бы написать это:

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

1 Ответ

0 голосов
/ 06 июля 2018

Вы можете сделать 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 в качестве параметра, вы потеряете эту проверку типов во время компиляции.

...