网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 其他技术区 > 游戏开发 >

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

时间:2025-11-04 00:07

人气:

作者:admin

标签:

导读:有些情况下我们会对字段做泛型封装,使其支持OnChange、IsDirty等统一的功能扩展,例如: IObservablelt;floatgt; hitPoint; 而有些字段有挂载修改器的需求(例如某属性挂载修改器让数值*1.2倍)...

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

IObservable<float> hitPoint;

 

而有些字段有挂载修改器的需求(例如某属性挂载修改器让数值*1.2倍)修改器若使用lambda则对序列化不友好,

因此考虑自行封装四则运算供修改器给原始数值进行修改,但C#早期没有四则运算的接口(Interface)。

网上的dynamic动态类型做法对多平台也不太好。

(注:使用扩展方法实现的特化,和这类泛型内特化不太一样)

(注2:用C#自带的IConvertible操作结束要转回T类型;有额外开销)

 

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

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()
    {
        // 假设都是乘操作,省略逻辑
        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
    }
}

 

 

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

#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);
}

 

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
  • 便捷打包Instant Asset脚本

    便捷打包Instant Asset脚本

    使用说明 将脚本放在Assets/Editor目录下 在需要打包同一个table的资源要放在同一...
  • Tuanjie InstantAsset

    Tuanjie InstantAsset

    InstantAsset InstantAsset 是一套全新的资产解决方案,旨在提升开发者的开发和运行...
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信