首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >设置无反射的ReadOnly字符串

设置无反射的ReadOnly字符串
EN

Stack Overflow用户
提问于 2016-07-08 21:50:54
回答 4查看 117关注 0票数 0

我正在开发一个需要访问公共字符串的应用程序。然而,我也希望限制写访问。因为我有很多字符串,所以我想避免每个字符串都有一个getter和private setter。

请参阅以下代码:

代码语言:javascript
运行
复制
public readonly string privateMem, peakVM, peakPaged, pagedSysMem, pagedMem, nonpagedSysMem;

    public override void Capture()
    {
        using (Process p = Process.GetCurrentProcess())
        {

            // Throws error as privateMem can't be assigned a value

            privateMem = string.Format("{0:N0} K", p.PrivateMemorySize64 / 1024);
            peakVM = string.Format("{0:N0} K", p.PeakVirtualMemorySize64 / 1024);
            peakPaged = string.Format("{0:N0} K", p.PeakPagedMemorySize64 / 1024);
            pagedSysMem = string.Format("{0:N0} K", p.PagedSystemMemorySize64 / 1024);
            pagedMem = string.Format("{0:N0} K", p.PagedMemorySize64 / 1024);
            nonpagedSysMem = string.Format("{0:N0} K", p.NonpagedSystemMemorySize64 / 1024);
        }

    }    

我知道有一些方法可以通过反射为只读字段赋值,但是我从其他几个堆栈溢出问题中发现这是一个糟糕的想法。

所以总结一下:

如何在没有反射的情况下为只读字符串赋值,或者不使用冗长的getter和setter是否存在更好的解决方案?

有没有一种方法可以声明一个变量,为它赋值,然后将它指定为只读?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-07-09 00:36:19

您当前使用字典的答案是不正确的,因为它不是只读的。

一种更正确的方法是基于字典初始化一次IReadOnlyDictionary (在.NET 4.5或更高版本中)实例,然后添加逻辑以防止在初始化后被新值覆盖。

通过使用支持字段,我们可以确保即使在类内部发生修改它的尝试,一旦它包含值,它也不会被覆盖。

代码语言:javascript
运行
复制
private IReadOnlyDictionary<string, string> _memoryStrings;
public IReadOnlyDictionary<string, string> memoryStrings
{
    get
    {
        return _memoryStrings;
    }
    private set
    {
        if (_memoryStrings != null && _memoryStrings.Count() > 0) return;
        _memoryStrings = value;
    }
}

public void Capture()
{
    if (memoryStrings == null || memoryStrings.Count() == 0)
    {
        using (Process p = Process.GetCurrentProcess())
        {
            memoryStrings = new Dictionary<string, string>
            {
                {"privateMem", string.Format("{0:N0} K", p.PrivateMemorySize64 / 1024)},
                {"peakVm", string.Format("{0:N0} K", p.PeakVirtualMemorySize64 / 1024)},
                {"peakPaged", string.Format("{0:N0} K", p.PeakPagedMemorySize64 / 1024)},
                {"pagedSysMem", string.Format("{0:N0} K", p.PagedSystemMemorySize64 / 1024)},
                {"pagedMem", string.Format("{0:N0} K", p.PagedMemorySize64 / 1024)},
                { "nonpagedSysMem", string.Format("{0:N0} K", p.NonpagedSystemMemorySize64 / 1024)}
            };
        }
    }
}

这为我们提供了多个级别的不变性。

如果您多次调用Capture(),它将只在第一次运行计算。

如果您尝试覆盖类中其他位置的字典,则一旦它包含值,它就不会被覆盖。

如果在创建集合后尝试覆盖属性或添加值,您将收到编译时异常(在使用索引器或尝试使用.Add()方法的情况下)或运行时异常(在通过强制转换为IDictionary使用.Add()方法的情况下)。

票数 0
EN

Stack Overflow用户

发布于 2016-07-08 21:58:55

你正在尝试做的事情毫无意义。只读字段只能在构造函数中填充。它们对于依赖注入非常有用,例如,只能在构造函数内设置内容,而且不能在构造函数之外修改。

例如,您可以始终使用私有集合。说getter和setter是“冗长的”也是没有意义的。他们出现在那里是有原因的。试图找到一种不同的方式来做事情,很可能意味着疯狂的代码和所有这些仅仅是为了避免使用简单的setter?

想想你在做什么,为什么要做,最后问问自己,这真的值得吗?

票数 7
EN

Stack Overflow用户

发布于 2016-07-08 23:26:55

我最后只用了一本字典。这样,我只需要一个getter和private setter,而且以后添加更多字符串/系统信息时,伸缩性更强。

代码语言:javascript
运行
复制
public Dictionary<string, string> memoryStrings
         {
             get;
             private set;
         }

        public MemoryUsageFragment() {
            memoryStrings = new Dictionary<string, string>();
        }

        public override void Capture()
        {
            using (Process p = Process.GetCurrentProcess())
            {
                memoryStrings.Add("privateMem", string.Format("{0:N0} K", p.PrivateMemorySize64 / 1024));
                memoryStrings.Add("peakVm", string.Format("{0:N0} K", p.PeakVirtualMemorySize64 / 1024));
                memoryStrings.Add("peakPaged", string.Format("{0:N0} K", p.PeakPagedMemorySize64 / 1024));
                memoryStrings.Add("pagedSysMem", string.Format("{0:N0} K", p.PagedSystemMemorySize64 / 1024));
                memoryStrings.Add("pagedMem", string.Format("{0:N0} K", p.PagedMemorySize64 / 1024));
                memoryStrings.Add("nonpagedSysMem", string.Format("{0:N0} K", p.NonpagedSystemMemorySize64 / 1024));
            }    
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38268379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档