- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这可以应用于多个问题,其中列表的项目数量有限,例如城市、货币、语言等的列表。
我正在尝试找到一种方法将一个类序列化为它的 Id,然后反序列化回它的完整描述。例如,如果我们有这样的城市结构:
public struct City
{
public string Name;
public Country Country;
}
[JsonObject(MemberSerialization.OptIn)]
public class Country
{
public Country(string code, string name) { Code = code; Name = name; }
[JsonProperty]
public string Code;
public string Name;
}
public class Countries
{
public static List<Country> All = new List<Country>()
{
new Country("US", "United States"),
new Country("GB", "United Kingdom"),
new Country("FR", "France"),
new Country("ES", "Spain"),
};
}
我不介意序列化为 {"code":"ES"} 或简称为“ES”的国家/地区,但我希望将其反序列化为 Countries.All 中国家/地区的现有实例
我怎么会出现这种行为?
最佳答案
您有两个解决方案:
我很快就会有例子,我需要先把它们打出来。编辑:示例完成
两种情况
在这两个示例中,我都使用 JsonConvertAttribute 来设置在序列化或反序列化对象时应使用哪个转换器。此参数告诉 json.net 库在默认情况下序列化对象/参数时使用哪个类/转换器。
如果您只需要在特定时刻进行序列化,则必须针对 2 种不同的场景进行选择:
将国家/地区保留在对象/结构中
在我看来,此选项是 2 种解决方案中最灵活和实用的,因为它允许更改需求并减少异常抛出。
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyApplication
{
public struct City
{
public string Name;
// you could also set a converter for this field specifically if you only need for specific fields but also
// still want it to display as a normal json object when you serialise the object.
// [JsonConverter(typeof(CountryConverter))]
public Country Country;
}
// Setting a json converter attribute allows json.net to understand that an object by default
// will be serialised and deserialised using the specified converter.
[JsonConverter(typeof(CountryConverter))]
public class Country
{
public Country(string code)
{
switch (code)
{
case "US": Name = "United-States"; break;
case "GB": Name = "United Kingdom"; break;
case "FR": Name = "France"; break;
case "ES": Name = "Spain"; break;
case "CA": Name = "Canada"; break;
}
}
public string Code { get; set; }
public string Name { get; set; }
}
public class CountryConverter : JsonConverter<Country>
{
// Assuming that the countries are serialised using the code
public override Country ReadJson(JsonReader reader, Type objectType, Country existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if(reader.Value == null && reader.ValueType == typeof(string))
{
return null;
}
string code = (string) reader.Value;
code = code.ToUpperInvariant(); // Because reducing error points is usually a good thing
return new Country(code);
}
public override void WriteJson(JsonWriter writer, Country value, JsonSerializer serializer)
{
//Writes the code as the value for the object
writer.WriteValue(value.Code);
}
}
}
将国家/地区更改为枚举
使用枚举可能很棒,因为它允许您拥有一组不变的值,而不必一遍又一遍地创建新对象。但这会使您的转换逻辑稍微复杂一些。
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyApplication
{
public struct City
{
public string Name;
public Country Country;
}
// Using the full name as it makes it easier to work with and also because you'd need a json converter
// if you want a string and not the number/index of the country when you serialise the data
[JsonConverter(typeof(CountryConverter))]
public enum Country
{
UnitedStates,
UnitedKingdom,
France,
Spain,
Canada
}
// this class only exists for you to add extentions to this enums.
// In short extentions are a type of methods added to other classes that act
// as if they were part of outher classes. usually this means that the first parameter
// is prefixed by this.
public static class CountryExtentions
{
public static string GetCode(this Country country)
{
switch (country)
{
case Country.UnitedStates: return "US";
case Country.UnitedKingdom: return "GB";
case Country.France: return "FR";
case Country.Spain: return "SP";
case Country.Canada: return "CA";
default: throw new InvalidOperationException($"This country has no code {country.ToString()}");
}
}
}
public class CountryConverter : JsonConverter<Country>
{
// Assuming that the countries are serialised using the code
public override Country ReadJson(JsonReader reader, Type objectType, Country existingValue, bool hasExistingValue, JsonSerializer serializer)
{
// make sure you can convert the thing into a string
if (reader.Value == null && reader.ValueType == typeof(string))
{
throw new InvalidOperationException($"The data type passed {reader.ValueType.Name} isn't convertible. The data type musts be a string.");
}
// get the value
string code = (string)reader.Value;
code = code.ToUpperInvariant(); // Because reducing error points is usually a good thing
// cycle through the enum values to compare them to the code
foreach (Country country in Enum.GetValues(typeof(Country)))
{
// if the code matches
if (country.GetCode() == code)
{
// return the country enum
return country;
}
}
// if no match is found, the code is invlalid
throw new InvalidCastException("The provided code could not be converted.");
}
public override void WriteJson(JsonWriter writer, Country value, JsonSerializer serializer)
{
//Writes the code as the value for the object
writer.WriteValue(value.GetCode());
}
}
}
关于c# - 反序列化到 C# 中类的现有实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49482530/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!