實現(xiàn)C#泛型四則運算等特化操作
有些情況下我們會對字段做泛型封裝,使其支持OnChange、IsDirty等統(tǒng)一的功能擴(kuò)展,例如:
IObservable<float> hitPoint;
而有些字段有掛載修改器的需求,修改器若使用lambda則對序列化不友好,因此考慮自行封裝四則運算供修改器
給原始數(shù)值進(jìn)行修改,但C#早期沒有四則運算的接口(Interface)。網(wǎng)上的dynamic動態(tài)類型做法對多平臺也不太好。
(注:使用擴(kuò)展方法實現(xiàn)的特化,和這類泛型內(nèi)特化不太一樣)
不轉(zhuǎn)弱類型的情況下,仍考慮通過接口解決,代碼如下:
public interface IArithmeticOperator<T> { public T Add(T x, T y); public T Sub(T x, T y); public T Mul(T x, T y); public T Div(T x, T y); } public static class ArithmeticOperator<T> { public static IArithmeticOperator<T> Instance; static ArithmeticOperator() { var type = typeof(T); if (type == typeof(int)) Instance = (IArithmeticOperator<T>)(object)new IntAritOp(); else if (type == typeof(float)) Instance = (IArithmeticOperator<T>)(object)new FloatAritOp(); } } public class IntAritOp : IArithmeticOperator<int> { public int Add(int x, int y) => x + y; public int Div(int x, int y) => x / y; public int Mul(int x, int y) => x * y; public int Sub(int x, int y) => x - y; } public class FloatAritOp : IArithmeticOperator<float> { public float Add(float x, float y) => x + y; public float Div(float x, float y) => x / y; public float Mul(float x, float y) => x * y; public float Sub(float x, float y) => x - y; } public class AttributeModifier<T> { private T _delta; public AttributeModifier(T delta) { this._delta = delta; } public T Add(T current) => ArithmeticOperator<T>.Instance.Add(current, _delta); public T Sub(T current) => ArithmeticOperator<T>.Instance.Sub(current, _delta); public T Mul(T current) => ArithmeticOperator<T>.Instance.Mul(current, _delta); public T Div(T current) => ArithmeticOperator<T>.Instance.Div(current, _delta); } public class Attribute<T> { private T _Value; private AttributeModifier<T> _Modifier; public Attribute(T value, AttributeModifier<T> modifier) { _Value = value; _Modifier = modifier; } public T GetValue() { // 假設(shè)都是乘操作,省略邏輯 return _Modifier.Mul(_Value); } } public class Test01 : MonoBehaviour { void Start() { var hp = new Attribute<int>(100, new AttributeModifier<int>(10)); Debug.Log(hp.GetValue());//1000 var stamina = new Attribute<float>(25.5f, new AttributeModifier<float>(2f)); Debug.Log(stamina.GetValue());//51 } }
而如果需要擴(kuò)展,如屬性修改器需要直接在泛型類的基礎(chǔ)上支持序列化接口,可以這么寫:
#region BinarySerializeOperator public interface IBinarySerializeOperator<T> { public void Serialize(BinaryWriter writer, T inValue); public T Deserialize(BinaryReader reader); } public static class BinarySerializeOperator<T> { public static IBinarySerializeOperator<T> Instance; static BinarySerializeOperator() { var type = typeof(T); if (type == typeof(int)) Instance = (IBinarySerializeOperator<T>)(object)new IntBinSeriOp(); else if (type == typeof(float)) Instance = (IBinarySerializeOperator<T>)(object)new FloatBinSeriOp(); } } public class IntBinSeriOp : IBinarySerializeOperator<int> { public int Deserialize(BinaryReader reader) { return reader.ReadInt32(); } public void Serialize(BinaryWriter writer, int inValue) { writer.Write(inValue); } } public class FloatBinSeriOp : IBinarySerializeOperator<float> { public float Deserialize(BinaryReader reader) { return reader.ReadSingle(); } public void Serialize(BinaryWriter writer, float inValue) { writer.Write(inValue); } } #endregion public class AttributeModifier<T> { private T _delta; public AttributeModifier(T delta) { this._delta = delta; } public T Add(T current) => ArithmeticOperator<T>.Instance.Add(current, _delta); public T Sub(T current) => ArithmeticOperator<T>.Instance.Sub(current, _delta); public T Mul(T current) => ArithmeticOperator<T>.Instance.Mul(current, _delta); public T Div(T current) => ArithmeticOperator<T>.Instance.Div(current, _delta); public void Serialize(BinaryWriter writer) => BinarySerializeOperator<T>.Instance.Serialize(writer, _delta); public void Deserialize(BinaryReader reader) => _delta = BinarySerializeOperator<T>.Instance.Deserialize(reader); }
浙公網(wǎng)安備 33010602011771號