Добавлен Devion,
опубликован
При работе в Unity нам может понадобиться использовать классы-капсулы для сериализации некоторых нативных классов. Зачастую среди кандидатов на такие вот классы у нас используются классы, в которых есть откуда подтянуть эти данные. Среди таких - классы для работы с рефлексией.
базовый класс
namespace Serialization
{
public abstract class SerializeContainer<T>
where T: class
{
private T _value;
public T value
{
get
{
if (isNull)
return null;
if (_value == null && !isNull)
_value = Getter();
isNull = _value == null;
return _value;
}
set
{
_value = value;
isNull = (value == null);
if (!isNull)
Setter(value);
}
}
public bool isNull = true;
protected abstract T Getter();
protected abstract void Setter(T value);
}
}
Type
using System;
namespace Serialization
{
[Serializable]
public class SerializeType : SerializeContainer<Type>
{
public SerializeType() { value = null; }
public SerializeType(Type value) { this.value = value; }
public string fullName;
protected override Type Getter()
{
return Type.GetType(fullName);
}
protected override void Setter(Type value)
{
fullName = value.AssemblyQualifiedName ?? "";
}
}
}
FIeldInfo
using System;
using System.Reflection;
namespace Serialization
{
[Serializable]
public class SerializeFieldInfo : SerializeContainer<FieldInfo>
{
public SerializeFieldInfo() { value = null; }
public SerializeFieldInfo(FieldInfo value) { this.value = value; }
public SerializeFieldInfo(Type type, string fieldname)
{
this.s_parentType = new SerializeType(type);
this.fieldname = fieldname;
}
public SerializeType s_parentType;
public string fieldname;
protected override FieldInfo Getter()
{
return s_parentType.value.GetField(fieldname);
}
protected override void Setter(FieldInfo value)
{
s_parentType = new SerializeType(value.DeclaringType);
fieldname = value.Name;
}
}
}
MethodInfo
using System;
using System.Linq;
using System.Reflection;
namespace Serialization
{
[Serializable]
public class SerializeMethod : SerializeContainer<MethodInfo>
{
public SerializeMethod() { value = null; }
public SerializeMethod(MethodInfo value) { this.value = value; }
public string[] parametersInfo;
public SerializeType s_parentType = new SerializeType();
public string methodName;
public int parameterCount { get { return parametersInfo.Length; } }
protected override MethodInfo Getter()
{
return s_parentType.value
.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)
.Where(x => x.Name == methodName)
.Where(x =>
{
var ps = x.GetParameters();
return ps.Length == parametersInfo.Length &&
!ps.Where((t, i) => GetParameterInfo(t) != parametersInfo[i]).Any();
}).FirstOrDefault();
}
protected override void Setter(MethodInfo value)
{
s_parentType = new SerializeType(value.DeclaringType);
parametersInfo = value.GetParameters().Select(x => GetParameterInfo(x)).ToArray();
methodName = value.Name;
}
private static string GetParameterInfo(ParameterInfo parameterInfo)
{
return parameterInfo.ToString();
}
}
}
Enum - не совсем в тему рефлексии, но тоже сериализатор
using System;
using System.Linq;
namespace Serialization
{
[Serializable]
public class SerializeEnum : SerializeContainer<Enum>
{
public SerializeType type;
public int index;
protected override Enum Getter()
{
return Enum.Parse(type.value, Enum.GetNames(type.value)[index]) as Enum;
}
protected override void Setter(Enum value)
{
type = new SerializeType(value.GetType());
index = Enum.GetValues(value.GetType()).Cast<Enum>().ToList().FindIndex(x => x.Equals(value));
}
}
}
MethodInfo оказался объемным, но зато так он поддерживает дженерик параметры.
Указанные сериализаторы позволяют хранить типы. Например:
myTypeStorage = new SerializeType(typeof(int));
var myType = myTypeStorage.value;
Плюсом является то, что при этом капсула адекватно сохраняется в сцене (в то время как сам по себе тип сохранить нельзя).
Так как вычисления методов происходят "ленивым кешированием" расчеты будут произведены только при первом обращении к полю value.
Так как вычисления методов происходят "ленивым кешированием" расчеты будут произведены только при первом обращении к полю value.
Где применять?
Да хоть где. Лично мне понадобилось для написания редактора сценариев, ибо там методы/типы/поля дело очень важное.
Да хоть где. Лично мне понадобилось для написания редактора сценариев, ибо там методы/типы/поля дело очень важное.
Комментарии пока отсутcтвуют.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.