仅包含可序列化对象的字典
本文关键字:字典 对象 序列化 包含可 | 更新日期: 2023-09-27 18:05:39
我正在寻找一种方法来确保只有可序列化的对象被存储到c#中的字典中。
更具体地说,我希望做类似这样的事情:
Dictionary<String, ISerializable> serialDict = new Dictionary<String, ISerializable>();
这样做的问题是,我不能存储基本类型,如整数、布尔值或字符串。
是否有一种方法来确保我的字典只包含可以序列化的对象?
我不认为你可以在编译时这样做,但你可以在运行时这样做。如果你建立自己的类,从Dictionary<TKey, TValue>
派生,然后在你的类的构造函数中,你可以检查附加到TValue
类型的属性,并确保SerializableAttribute
是其中之一,否则抛出异常。
所有的标准基元类型(int
、bool
等)都有这个属性。
需要考虑的一件事是,在可序列化的类中使用SerializableAttribute标记,而不是实现接口。从MSDN:
任何可能被序列化的类都必须用SerializableAttribute。如果一个类需要控制它的序列化进程,它可以实现isserializable接口。
你需要做的是创建自己的类来实现idictioany接口,并且每次有人调用add时,使用反射来检查传入的元素是否具有可序列化的属性(如果没有则抛出异常)。
代码看起来像
class MyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> d;
public void Add(TKey key, TValue value)
{
if( value.GetType().IsSerializable )
{
d.Add(key, value);
}
else
{
throw new ArgumentException();
}
}
.....
}
[Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
static SerializableDictionary()
{
AssertSerializable(typeof(TKey));
AssertSerializable(typeof(TValue));
}
static void AssertSerializable(Type t)
{
if (!t.IsSerializable)
{
throw new NotSupportedException(string.Format(
"{0} is not serializable", t.Name));
}
}
}
一个答案是创建一个serializableprimary包装器类。
class SerializablePrimative<T> : ISerializable {
private T val = default();
private SerializablePrimative(T newVal){
val = newVal;
}
public static boolean IsSupported(Object o){
if (o == null){
return false;
}else{
return IsSupported(o.GetType());
}
}
public static boolean IsSupported(Type t){
if (// you want to support* ...)
{
return true;
}
else
{
return false;
}
}
public static SerializablePrimative GetSerializable(Object o){
if (IsSupported(o)){
return //Intstatiate via Reflection **
}else {
return null;
}
}
}
其余部分留给读者作为练习,但基本上是创建一个适配器来使这些特定类型"适合"您的字典。
*参见:数据契约序列化器支持的类型
**参见:c#:在。net中使用反射实例化泛型类
怎么包装你的字典?
class SomeClass {
Dictionary<string,object> d;
// add ISerializable
public void Add(string key, ISerializable value) {
d[key] = value;
}
// add primitive types
public void Add(string key, bool value) {
d[key] = value;
}
public void Add(string key, int value) {
d[key] = value;
}
// etc ...
}
通过这种方式,您可以确保只能添加可序列化的对象和基本类型。