c#万能变量

0.修改(2026年1月23日14:18:17)

考虑到复用还是继承一下IPool对象池接口

对象池我会在另外一篇文章中发布

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//定义对象池接口 
namespace SCGPool
{
    public interface IPool
    {
        /// <summary>
        /// 调用Get的时候 执行 
        /// </summary>
        public void OnGet();
        /// <summary>
        /// 
        /// 
        /// </summary>
        public void OnRelease();

    }
}

1.背景:

接手的项目打开一个界面使用接口UIManager.ShowWindow<T>(parame object[] obj) 类似这种打开窗口的设计这导致我要加个参数变得比较艰难,牵涉到太多修改放弃了。我个人认为比较好的接口设计是参数使用结构体比如

这种参数众多的情况有时候设计成结构体能方便扩展,在比如设置头像的接口 也是结构体

2.现在的业务层调用情况已聊天系统为例

这里传递了n多个参数,让接手的人没法做后续功能了

这实在是让人无比难受,可能我真的只需要一个参数比如就叫Varient 变量,你需要什么去容器中拿即可。于是就有了这篇文章。

3.实现代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SCGPool;

public class Variant : IPool
{

    private bool isNull
    {
        get { return m_value == null; }
        set { if (value == true) { m_value = null; } }
    }

    private void set_bool(bool b)
    { m_value = b; }

    private void set_value(double b)
    { m_value = b; }

    private void set_int(int b)
    { m_value = b; }

    private void set_string(string b)
    { m_value = b; }

    private bool get_bool()
    {
        if (m_value == null || m_value.GetType() != typeof(bool))
        { return false; }
        return (bool)m_value;
    }

    private double get_value()
    {
        if (m_value == null || m_value.GetType() != typeof(double))
        { return 0; }
        return (double)m_value;
    }

    private int get_int()
    {
        if (m_value == null || m_value.GetType() != typeof(int))
        { return 0; }
        return (int)m_value;
    }

    private string get_string()
    {
        if (m_value == null)
        { return ""; }
        return m_value.ToString();
    }

    private void set_object(object a)
    { m_value = a; }

    private void set_json(string data)
    {
        try
        {
            JToken token = JToken.Parse(data);
            _json_add(token, this);
        }
        catch (System.Exception ex)
        {
            Debug.LogError(ex.ToString());
            m_value = null;
        }
    }

    private string to_json()
    {
        JToken token = _json_get(this);
        if (token == null) { return "{}"; }
        return token.ToString(Formatting.None);
    }

    static void _json_add(JToken token, Variant v)
    {
        switch (token.Type)
        {
            case JTokenType.Object:
                _json_add_obj((JObject)token, v);
                break;
            case JTokenType.Array:
                _json_add_list((JArray)token, v);
                break;
            case JTokenType.Boolean:
                _json_add_bool((bool)token, v);
                break;
            case JTokenType.Integer:
                _json_add_int((int)token, v);
                break;
            case JTokenType.Float:
                _json_add_double((double)token, v);
                break;
            default:
                _json_add_string(token.ToString(), v);
                break;
        }
    }

    static void _json_add_obj(JObject obj, Variant v)
    {
        Dictionary<string, Variant> map = v.to_name_map();
        if (map == null)
        { return; }

        foreach (var property in obj.Properties())
        {
            JToken token = property.Value;
            map[property.Name] = new Variant();
            _json_add(token, map[property.Name]);
        }
    }

    static void _json_add_list(JArray array, Variant v)
    {
        var list = v.to_list();

        for (int i = 0; i < array.Count; i++)
        {
            var sub = new Variant();
            list.Add(sub);
            _json_add(array[i], sub);
        }
    }

    static void _json_add_bool(bool value, Variant v)
    {
        v.set_bool(value);
    }

    static void _json_add_int(int value, Variant v)
    {
        v.m_value = value;
    }

    static void _json_add_double(double value, Variant v)
    {
        v.m_value = value;
    }

    static void _json_add_string(string value, Variant v)
    {
        v.m_value = value;
    }

    static JToken _json_get(Variant v)
    {
        if (v.m_value == null)
        {
            return null;
        }

        if (v.m_value.GetType() == typeof(Dictionary<string, Variant>))
        {
            JObject obj = new JObject();
            foreach (var kv in ((Dictionary<string, Variant>)v.m_value))
            {
                JToken token = _json_get(kv.Value);
                if (token != null)
                {
                    obj[kv.Key] = token;
                }
            }
            return obj;
        }
        else if (v.m_value.GetType() == typeof(List<Variant>))
        {
            JArray array = new JArray();
            foreach (var kv in ((List<Variant>)v.m_value))
            {
                JToken token = _json_get(kv);
                if (token != null)
                {
                    array.Add(token);
                }
            }
            return array;
        }
        else if (
        v.m_value.GetType() == typeof(int) ||
        v.m_value.GetType() == typeof(double) ||
        v.m_value.GetType() == typeof(bool))
        {
            return new JValue(v.m_value);
        }
        else
        {
            return new JValue(v.m_value.ToString());
        }
    }

    private object get_object(string type)
    {
        Type t = Type.GetType(type);
        if (t == null) { return null; }
        if (m_value == null) { return null; }
        if (m_value.GetType() != t) { return null; }
        return m_value;
    }

    private string to_string()
    {
        if (m_value == null) { return ""; }
        return m_value.ToString();
    }

    private double to_double(double def)
    {
        string sv = to_string();
        double ret = def;
        if (double.TryParse(sv, out ret))
        { return ret; }
        return def;
    }

    private float to_float(float def)
    {
        return (float)to_double((double)def);
    }

    private int to_int(int def)
    {
        return (int)to_double((double)def);
    }

    private object[] list_to_params()
    {
        if (m_value == null || m_value.GetType() != typeof(List<Variant>))
        { return new object[0]; }
        var l = to_list();
        if (l == null || l.Count == 0)
        { return new object[0]; }
        object[] pl = new object[l.Count];
        for (int i = 0; i < l.Count; i++)
        { pl[i] = l[i].m_value; }
        return pl;
    }

    private List<Variant> to_list()
    {
        if (m_value != null && m_value.GetType() == typeof(List<Variant>))
        { return (List<Variant>)m_value; }
        List<Variant> l = new List<Variant>();
        m_value = l;
        return l;
    }

    private Dictionary<int, Variant> to_map()
    {
        if (m_value != null && m_value.GetType() == typeof(Dictionary<int, Variant>))
        { return (Dictionary<int, Variant>)m_value; }
        Dictionary<int, Variant> xx = new Dictionary<int, Variant>();
        m_value = xx;
        return xx;
    }

    private Dictionary<int, Variant> get_map()
    {
        if (m_value is Dictionary<int, Variant>)
        {
            return (Dictionary<int, Variant>)m_value;
        }
        return null;
    }

    private Dictionary<string, Variant> get_name_map()
    {
        if (m_value is Dictionary<string, Variant>)
        {
            return (Dictionary<string, Variant>)m_value;
        }
        return null;
    }

    private Dictionary<string, Variant> to_name_map()
    {
        if (m_value != null && m_value.GetType() == typeof(Dictionary<string, Variant>))
        { return (Dictionary<string, Variant>)m_value; }
        Dictionary<string, Variant> xx = new Dictionary<string, Variant>();
        m_value = xx;
        return xx;
    }

    private Variant push_in_list()
    {
        var n = new Variant();
        to_list().Add(n);
        return n;
    }

    private Variant get_in_list(int id)
    {
        List<Variant> v = to_list();
        if (v == null)
        {
            return null;
        }

        if (id < 0 || id >= v.Count)
        {
            return null;
        }

        return v[id];
    }

    private Variant apply_in_map(int id)
    {
        var v = to_map();
        if (!v.ContainsKey(id))
        { v[id] = new Variant(); }
        return v[id];
    }

    private Variant apply_in_name_map(string n)
    {
        var v = to_name_map();
        if (!v.ContainsKey(n))
        { v[n] = new Variant(); }
        return v[n];
    }

    public override string ToString()
    {
        if (m_value == null)
        { return "Variant:null"; }
        return "Variant:" + m_value.GetType().Name + ":" + m_value.ToString();
    }

 

  
    public T Get<T>(string mapKey)
    {      
        return (T)Convert.ChangeType(this.apply_in_name_map(mapKey).m_value, typeof(T));        
    }
    
 

    public void Set<T>(string mapKey, T value)
    {
        this.apply_in_name_map(mapKey).m_value = value;
    }



    public void Dispose()
    {
        var nameMap = get_name_map();
        if (nameMap != null)
        {
            foreach (var item in nameMap)
            {
                item.Value.Dispose();
            }
        }
        var map = get_map();
        if (map != null)
        {
            foreach (var item in map)
            {
                item.Value.Dispose();
            }
        }
        if (m_value is Dictionary<int, Variant>)
        {
            ((Dictionary<int, Variant>)m_value).Clear();
        }
        else if (m_value is Dictionary<string, Variant>)
        {
            ((Dictionary<string, Variant>)m_value).Clear();
        }
        m_value = null;
    }

    public void OnGet()
    {
        
    }

    public void OnRelease()
    {
        this.Dispose();
    }

    object m_value = null;
}

4.测试用例

cs 复制代码
 Variant test = new();
 test.Set("helloworld", 1);
 int hello = test.Get<int>("helloworld");

 test.Set("okok", true);
 bool okok = test.Get<bool>("okok");

5对象池使用

cs 复制代码
var varient = PoolManager.Get<Variant>();
// {0}玩家在世界频道发了斋月高级宝箱,点击疯抢!
varient.Set("hello", 1);


PoolManager.Release<Variant>(varient)
相关推荐
GGGG寄了2 小时前
HTML——文本标签
开发语言·前端·html
yangSnowy2 小时前
PHP变量回收机制
开发语言·php
C+-C资深大佬2 小时前
C++类型判断
开发语言·c++
2501_944521592 小时前
Flutter for OpenHarmony 微动漫App实战:推荐动漫实现
android·开发语言·前端·javascript·flutter·ecmascript
不绝1912 小时前
C#进阶:委托
开发语言·c#
喜欢喝果茶.2 小时前
跨.cs 文件传值(C#)
开发语言·c#
就是有点傻2 小时前
C#中如何和欧姆龙进行通信的
c#
zmzb01032 小时前
C++课后习题训练记录Day74
开发语言·c++
小冷coding3 小时前
【Java】Dubbo 与 OpenFeign 的核心区别
java·开发语言·dubbo