Есть ли способ указать «тип текущего класса» в сигнатуре метода C #? - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь определить абстрактный класс, который будут расширять другие классы, и они должны иметь возможность сериализации себя в JSON и десериализации из JSON.Я хочу написать абстрактный класс примерно так:

public abstract class BaseApiModel {
    public abstract string ToJson();
    public abstract T FromJson(string json);
}

... где T - тип текущего класса.Затем я написал бы расширяющий класс, например:

public class ContactApiModel : BaseApiModel {
    public string ContactName { get; set; }
    [...other properties...]

    public override string ToJson() {
        [...return serialized JSON string...]
    }

    public override ContactApiModel FromJson(string json) {
        [...return deserialized object...]
    }
}

Конечно, это не работает, потому что T в абстрактном классе не определено.Но есть ли способ, которым я могу написать «этот метод должен возвращать тип текущего класса» в C #?Должен ли я просто заставить его вернуться object?Или я подхожу к этому неправильно, и есть лучший способ структурировать это?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Для будущих посетителей этого:

Более разумным решением было бы вообще не реализовывать этот метод в соответствующих классах и вместо этого использовать методы расширения:

public static class ExtendBaseApiModel
{
    public static string ToJson(this T obj) { /* ... */ }
    public static T FromJson<T>(this T obj, string json) where T : BaseApiModel { /* ... */ }
}

это позволит вам сохранить ваши классы красивыми и чистыми + свободными от затуманивания сериализации.

все же .. есть несколько слов, чтобы сказать

Как de -правильная сериализация

Предполагая, что это сделано для обеспечения настраиваемой сериализации внутри метода ToJson и настраиваемой десериализации внутри метода FromJson, тогда вам не следует использовать свои собственные странные методы, а скорее позволить инфраструктуре сделать это за вас..

Для Json.NET это должно быть сделано путем использования атрибута JsonConverter в классе и реализации соответствующего JsonConverter где-то

Интересный факт

Комбинируя вариант методов расширения с упомянутым выше JsonConverter, вы сможете просто сериализовать каждый объект, просто вызвав myobjvar.ToJson(...)

0 голосов
/ 25 сентября 2018

Вы можете объявить свой базовый класс, используя обобщенные значения, а в своем классе ContactApiModel просто установите для параметра T значение ContactApiModel, как показано ниже:

public abstract class BaseApiModel<T> {
    ...
    public abstract T FromJson(string json);
}


public class ContactApiModel : BaseApiModel<ContactApiModel> {
    ...
    public override ContactApiModel FromJson(string json) {
        [...return deserialized object...]
    }
}
...