找回密码
 立即注册

实现C#泛型四则运算等特化操作

擒揭 2025-11-4 11:34

有些情况下我们会对字段做泛型封装,使其支持OnChange、IsDirty等统一的功能扩展,例如:

[code]IObservable hitPoint;[/code]

 

而有些字段有挂载修改器的需求,修改器若使用lambda则对序列化不友好,因此考虑自行封装四则运算供修改器

给原始数值进行修改,但C#早期没有四则运算的接口(Interface)。网上的dynamic动态类型做法对多平台并不友好。

 

不转弱类型的情况下,仍考虑通过接口解决,代码如下:

[code]public interface IArithmeticOperator { 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 { public static IArithmeticOperator Instance; static ArithmeticOperator() { var type = typeof(T); if (type == typeof(int)) Instance = (IArithmeticOperator)(object)new IntAritOp(); else if (type == typeof(float)) Instance = (IArithmeticOperator)(object)new FloatAritOp(); } } public class IntAritOp : IArithmeticOperator { 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 { 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 { private T _delta; public AttributeModifier(T delta) { this._delta = delta; } public T Add(T current) => ArithmeticOperator.Instance.Add(current, _delta); public T Sub(T current) => ArithmeticOperator.Instance.Sub(current, _delta); public T Mul(T current) => ArithmeticOperator.Instance.Mul(current, _delta); public T Div(T current) => ArithmeticOperator.Instance.Div(current, _delta); } public class Test01 : MonoBehaviour { void Start() { var op01 = new AttributeModifier(10); var op02 = new AttributeModifier(2); int hitPoint = 0; hitPoint = op01.Add(hitPoint); hitPoint = op02.Mul(hitPoint); Debug.Log(hitPoint);//20 var op03 = new AttributeModifier(4.5f); var op04 = new AttributeModifier(2.2f); float stamina = 0f; stamina = op03.Add(stamina); stamina = op04.Mul(stamina); Debug.Log(stamina);//9.900001 } }[/code]

 

而如果需要扩展,如属性修改器需要直接在泛型类的基础上支持序列化,可以这么写:

[code]#region BinarySerializeOperator public interface IBinarySerializeOperator { public void Serialize(BinaryWriter writer, T inValue); public T Deserialize(BinaryReader reader); } public static class BinarySerializeOperator { public static IBinarySerializeOperator Instance; static BinarySerializeOperator() { var type = typeof(T); if (type == typeof(int)) Instance = (IBinarySerializeOperator)(object)new IntBinSeriOp(); else if (type == typeof(float)) Instance = (IBinarySerializeOperator)(object)new FloatBinSeriOp(); } } public class IntBinSeriOp : IBinarySerializeOperator { public int Deserialize(BinaryReader reader) { return reader.ReadInt32(); } public void Serialize(BinaryWriter writer, int inValue) { writer.Write(inValue); } } public class FloatBinSeriOp : IBinarySerializeOperator { public float Deserialize(BinaryReader reader) { return reader.ReadInt32(); } public void Serialize(BinaryWriter writer, float inValue) { writer.Write(inValue); } } #endregion public class AttributeModifier { private T _delta; public AttributeModifier(T delta) { this._delta = delta; } public T Add(T current) => ArithmeticOperator.Instance.Add(current, _delta); public T Sub(T current) => ArithmeticOperator.Instance.Sub(current, _delta); public T Mul(T current) => ArithmeticOperator.Instance.Mul(current, _delta); public T Div(T current) => ArithmeticOperator.Instance.Div(current, _delta); public void Serialize(BinaryWriter writer) => BinarySerializeOperator.Instance.Serialize(writer, _delta); public void Deserialize(BinaryReader reader) => _delta = BinarySerializeOperator.Instance.Deserialize(reader); }[/code]

如果有需要,再通过部分类就可以做到在同一程序集下,可解耦的扩展功能。


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

路过

雷人

握手

鲜花

鸡蛋
文章点评
学习中心
站长自定义文字内容,利用碎片时间,随时随地获取优质内容。