首页 > 编程语言 >今天才知道原来C#操作符重载函数中可以访问私有成员

今天才知道原来C#操作符重载函数中可以访问私有成员

时间:2024-06-21 11:09:50浏览次数:29  
标签:span C# private var int 操作符 value 重载 splitCharacter

起因

为了方便比较版本号,所以想到用 struct 封装一个结构体并重载它的操作符.

因为不常使用操作符重载,以为它的成员访问级别应该和普通的静态函数没有区别

直到使用时无意间发现

它竟然能访问到对应成员的私有成员 !!!

从而可以做到在重载类型操作时不必要公开一些成员访问, 达到类似 C++ 友元函数 的成员访问的效果(但是不能像C++一样在其他类中定义,只能在该类中定义) 非常便捷

例如:
image

也可以访问私有函数

image

完整代码


using System.Collections.Immutable;
using System.Security.Cryptography;

VersionNumberString v = "3.1.5";

struct VersionNumberString
{
    private string _value;
    private char _splitCharacter;
    private Lazy<ImmutableArray<int>> _parts;
    
    private const char  DEFAULT_SPLIT_CHARACTER_A = '.';
    
    private const char  DEFAULT_SPLIT_CHARACTER_B = ',';
    
    private const char  DEFAULT_SPLIT_CHARACTER_C = '&';

    public VersionNumberString(string value, char splitCharacter)
    {
        _value = value;
        _splitCharacter = splitCharacter;
        _parts = new(InitParts);
    }
    
    public static implicit operator string(VersionNumberString v)
    {
        return v._value;
    }
    
    public static implicit operator VersionNumberString(string version)
    {
        var splitCharacter = VersionNumberString.DetectSplitCharacter(version);
        
        return new VersionNumberString (version,splitCharacter);
    }
    
    private static char DetectSplitCharacter(string source)
    {
        var span = source.AsSpan();
        
        int index = span.IndexOfAny(
            DEFAULT_SPLIT_CHARACTER_A,
            DEFAULT_SPLIT_CHARACTER_B,
            DEFAULT_SPLIT_CHARACTER_C
        );
        
        // 有下标截取一个字符,没有下班直接移动到最后
        var range = index != -1
            ? span[index..(index+1)]
            : span[span.Length..];
            
        var e = range.GetEnumerator();
        
        if(!e.MoveNext())
        {
            return ' ';
        }
        
        return e.Current;
    }
    
    ImmutableArray<int> InitParts()
    {
        if(_splitCharacter ==' ')
        {
            return int.TryParse(_value,out int parsedVerion)
             ? ImmutableArray.Create<int>(parsedVerion)
             : ImmutableArray.Create<int>();
        }
        
        var span = _value.AsSpan();

        int startIndex = default;

        List<int> result = new(span.Length-1);

        for (int i = 0; i < span.Length; i++)
        {
            if (span[i] == _splitCharacter)
            {
                var n = int.Parse(span[startIndex..i]);

                result.Add(n);

                startIndex = i + 1;
            }
            else if (i == span.LastIndexOf(_splitCharacter) + 1)
            {
                var lastChar = span.Slice(i, span.Length - startIndex);

                result.Add(int.Parse(lastChar));
            }
        }

        return result.ToImmutableArray();
    }
}

标签:span,C#,private,var,int,操作符,value,重载,splitCharacter
From: https://www.cnblogs.com/ablewang/p/18260156

相关文章

  • 树形DP——AcWing 285. 没有上司的舞会
    目录树形DP定义运用情况注意事项解题思路AcWing285.没有上司的舞会 题目描述运行代码代码思路改进思路改进代码(AI)其它代码代码思路树形DP定义树形DP是在树上进行的动态规划。它利用树的结构特点,通过递归或迭代的方式,在每个节点上进行状态计算和转移,以求......
  • 数位统计DP——AcWing 338. 计数问题
    数位统计DP定义数位DP(DigitalDP)是一种用于解决与数字的数位相关问题的动态规划算法。它将数字的每一位看作一个状态,通过转移状态来计算满足特定条件的数字个数或其他相关统计信息。运用情况统计满足特定条件的数字个数,例如在给定范围内有多少个数字满足某些数位特征。计算......
  • Cannot generate SSPI context
         1.分析  1)获取服务器的SPN    a)通过SQLCheck.exe(需要到微软官网进行下载)    b)通过setspn工具  2)判断SPN是否正确,如果不正确则需要矫正SPN    a)如果好的连接找不到任何SPN则会使用NLTM    b)如果好的连接能找到......
  • 10条提升大模型任务微调效果的tricks
    在大型语言模型(LLMs)的研究和应用中,如何通过微调来适应特定任务是一个关键问题。尽管提示工程(PE)在提升LLMs的零样本学习和上下文内学习方面取得了显著成效,但关于如何设计有效的微调样本以进一步提升LLMs性能的研究还相对欠缺。为解决上述问题,提出了样本设计工程SDE(SampleDe......
  • React+TS前台项目实战(十四)-- 响应式头部导航+切换语言相关组件封装
    文章目录前言Header头部相关组件1.功能分析2.相关组件代码+详细注释3.使用方式4.Gif图效果展示总结前言在这篇博客中,我们将封装一个头部组件,根据不同设备类型来显示不同的导航菜单,会继续使用Reacthooks和styled-components库来构建这个组件,此外,也会实现切换......
  • C++ 面向对象高级开发 2、头文件与类的声明
       ObjectBased(基于对象)vs ObjectOriented(面向对象)ObjectBased:面对的是单一class的设计ObjectOriented:面对的是多重classes的设计,classes和classes之间的关系。         模板就是一种抽象......
  • mac苹果窗口辅助工具:Magnet for mac 2.14.0中文免激活版
    Magnet是一款针对MacOS系统的窗口管理工具软件。它能够帮助用户更加高效地管理和组织桌面上的窗口,通过简单的快捷键操作,可以将窗口自动调整到指定的位置和大小,实现多窗口快速布局。Magnet还支持多显示器环境下的窗口管理,可以让用户更加轻松地在多屏幕之间切换和布局窗口。......
  • apisix~为自定义插件设计一个configmap脚本
    configMapKubernetes中的ConfigMap是一种用来存储配置数据的API资源,它允许您将配置信息以键值对的形式保存,并在容器中使用这些配置信息。ConfigMap提供了一种将配置数据与应用程序解耦的方式,使得应用程序可以动态地获取配置而无需重新构建镜像。以下是ConfigMap的一些特......
  • 使用EventBus在Activity和fragment之间传递数据,出现post一次,却接收到多次对应事件
    背景项目中有一个activity,其中通过viewpager管理着多个页面,在activity操作某些数据时,通过eventbus将消息传递给fragment。该fragment中,分别在onViewCreated注册了eventbusif(!EventBus.getDefault().isRegistered(this)){EventBus.getDefault().register(this);}在onDes......
  • C++ 面向对象高级开发 3、构造函数
    1、内联函数inline 内联函数速度比较快 最终是不是inline实际上是由编译器决定的。 一般比较简单,编译器就能确定inline函数 2、AccessLevel访问级别  3、构造函数Construct默认实参。Defaultargument.充分利用构造函数的特殊语法,对数据进行初始化,这是一种比......