如何在抽象类中添加反序列化方法

时间:2019-03-18 08:21:21

标签: c# json .net-core

我有个主意,但我不知道该怎么做。

我创建了一个abstract class AJsonSerializer。我想在那里上SerializeDeserialize类。

public abstract class AJsonSerializer {
  public string ToJson() {
    return JsonConvert.SerializeObject(this);
  }

  public T FromJson<T>(string jsonString) where T : class {
    return JsonConvert.DeserializeObject<T>(jsonString);
  }
}

我有一个类User,该类是我从抽象类继承的:

public class User : AJsonSerializer {
  public string PublicKey { get; set; }
  public int User_ID { get; set; }
}

现在我可以那样做

internal static void Get_UserData(string username, ref User user) {
  if (ReadFromCache(username, out string value)) {
    user = user.FromJson<User>(value);
  } else {
    DataAccess.Get_UserData(username, out string user_public_key, out int id_user);

    user.PublicKey = user_public_key;
    user.User_ID = id_user;

    value = user.ToJson();

    SaveToCashe(username, value);
  }
}

这一行看起来很丑:user = user.FromJson<User>(value);

我想这样做:user.FromJson(value);

我知道如何在类User中进行操作(下面的示例),但是我想在抽象类中进行操作,然后此方法将对我所有的类都适用

错误的方法如何解决,只需将初始化程序添加到类User就像这样:

public User(string jsonString) {
  User user = JsonConvert.DeserializeObject<ApiUser>(jsonString);
  PublicKey = user.PublicKey;
  User_ID = user.User_ID;
}

2 个答案:

答案 0 :(得分:1)

您可以在类定义中声明泛型

public class User : AJsonSerializer<User>
{
    public string PublicKey { get; set; }
    public int User_ID { get; set; }
}
public abstract class AJsonSerializer<T>
    where T : class
{
    public string ToJson() {
        return JsonConvert.SerializeObject(this);
    }

    public static T FromJson(string jsonString) {
        return JsonConvert.DeserializeObject<T>(jsonString);
    }
}

编辑:正如Kara在他的评论中所述,您的FromJson方法可以是静态的。所以你可以这样称呼

var user = User.FromJson(jsonString);

答案 1 :(得分:1)

类似于Jerries的答案,另一种选择只是扩展方法。您可以将T限制为AJsonSerializer,使其仅限于其子类型。您无法覆盖扩展方法,但是在您的代码中,一开始就没有虚拟方法。

public static class SerializerExtensions {
   public static T FromJson<T>(this T obj, string json) where T:AJsonSerializer  {
       JsonConvert.PopulateObject(json, obj);
       return obj;
   }
}

这样,您将不需要在整个继承链中实现泛型类型的传递。 但是您需要初始化要访问的值,所以它将是:

var user = new User();
user.FromJson(jsonSTring);

var user = SerializerExtensions.FromJson(new User(), jsonString);

您的决定取决于您的用例。