【问题标题】:Can I prevent users from modify the parameters in C#我可以阻止用户修改C#中的参数吗
【发布时间】:2017-01-26 09:26:10
【问题描述】:

我正在为一群人使用 C# 编码,我正在设计要编码的方法的签名,我需要一种方法来确保人们不会修改他们将收到的某些参数。 它们接收大结构,因此它们是通过引用发送的,但我希望它们在不修改原始值的情况下使用数据。但由于结构很大,我们不想复制它们。

我们可以假设他们不想更改数据,我们只需要保护他们不犯错误。

C# 提供哪些解决方案?

这里是示例

class MyDataBlok {
    List<double> samples;
    int someParams;
    double lots of other params
    }

class MySetOfDataBlock
{
    List<MyDataBlock> DataSet;
    bool SomeParam;
    Double lots of other params;
}

class MethodsToBeCoded
{
    ProcessSetOfData( /*some tag defining data as protected*/ MySetOfDataBlock data)
    {
         //Here I want code that uses data without modifying data
         // nor the content on any data.DataSet[i]
    }
}

【问题讨论】:

  • 你应该看看单元测试。
  • 什么?! struct-instances 是按值传递的。无论如何我不明白你的问题。你能展示一些示例代码来说明你想要做什么吗?
  • 你不能阻止实现方法的人修改通过引用传递的参数。然而,由于 `struct´s 是通过 按值 传递的,因此该方法内的修改不会对调用代码产生任何影响。
  • @himbrombeere 使用struct 很好,除非它包含像List&lt;...&gt; 这样的引用类型成员,对吧?在这种情况下,添加/删除列表将反映在调用代码中?
  • 看看this已经被问及回答了。或this

标签: c# performance


【解决方案1】:

悲观的答案是。如果想要更改数据,他们。除了复制之外,您无能为力。


乐观的答案假设他们不想要更改数据,您只需要保护他们不犯错误。现在这是可能的:

不要给他们任何二传手。你没有说你的数据是什么样的,所以我只能给你一个模糊的描述:

不要暴露设置器。将它们提供给没有设置器的数据类的接口,将集合返回为IEnumerable&lt;&gt;,而不是它们的可修改实例等等。确保他们通过接口获取您的数据,您的数据不能被修改。

【讨论】:

  • 我现在添加了一个例子,我喜欢你所暴露的想法,你能具体一点吗?
  • @nvoigt 有人可以轻松地将IEnumerable&lt;&gt; 转换回List&lt;&gt;,他们可以进行修改。如果您尝试乐观,基类库可以解决所有问题! :)
  • @AkashKava 这是C#...如果你不复制,“邪恶”的人可以使用反射。非邪恶的人对IEnumerable 很好。任何解决方案都不是安全的,只是有帮助,因此用户更难犯错误。将 IEnumerable 强制转换为 List 并不是一个错误,它是故意的邪恶,在我看来属于第一类。
  • @AkashKava 我讨厌 .NET 使用的那些只读假货。他们给你一个IList,然后在你实际使用它作为IList的一半时间里抛出异常。这违反了我所知道的关于编程的任何准则。最简单的,易用性,你的名字。
  • @nvoigt,IEnumerableIList 不同,因为IList 具有Count 属性,IList 允许随机访问,IEnumerable 仅允许顺序访问。 IList 不一定是可修改的。它不是假的,它是关于如何访问“顺序”和“随机”的很好的指南,我认为它们是真正的计算标准。无论如何,您对IEnumerable 感到满意,并尝试始终按顺序访问对象并将随机访问称为某种违规行为,这完全是您的选择。
【解决方案2】:

如果您正在寻找类似 C++ 中的 const 键来防止数据的可变性,那么不幸的是,这不存在。

您可以做的是传递不可变类(没有数据修改属性或方法的类)。 -> 移除公共集;并且只使用只读方法

【讨论】:

    【解决方案3】:

    AsReadOnly()作为参数传递,任何人都不能修改。

    https://msdn.microsoft.com/en-us/library/e78dcd75(v=vs.110).aspx

     public void SomeMethod(IList<SomeData> list){
           ....
     }
    

    调用...

     SomeMethod( myList.AsReadOnly() );
    

    这样你就可以创建类了,

    Class MySetOfDataBlock
    {
        private List<MyDataBlock> _DataSet;
           = new List<MyDataBlock>();
    
        public IList<MyDataBlock> DataSet{
            get{
               return _DataSet.AsReadOnly();
            }
        }
    
    
    
        bool SomeParam;
        Double lots of other params;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多