6

I'm coding in C# for a group of people, I'm designing the signature of the methods to be coded and I need a way to ensure that people won't modify some parameters they will receive. They receive big structures so they are sent by reference, but I want they to consume the data without modifying the original values. But since the structures are big we don't want to make copies of them.

We can assume they don't want to change the data and we only need to protect them from making mistakes.

What solutions does C# offer?

Here's and example

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] } } 
7
  • You should take a look at unit testing. Commented Jan 26, 2017 at 9:27
  • 3
    What?! struct-instances are passed by value. Anyway I don´t understand your problem. Can you show some sample-code that shows what you´re trying to do? Commented Jan 26, 2017 at 9:27
  • 1
    You can´t prevent the person implementing a method to modify the arguments passed by reference. However as `struct´s are passed by value modifcations within that method don´t have any effect on the calling code. Commented Jan 26, 2017 at 9:31
  • 1
    @himbrombeere Using a struct is fine unless it contains reference type members like List<...>, right? In that case adding/removing to/from the list would reflect in the calling code? Commented Jan 26, 2017 at 9:34
  • 1
    Have a look at this It has already been asked and answered. or this Commented Jan 26, 2017 at 9:52

3 Answers 3

10

The pessimistic answer is None. If the want to change the data, they will. There is nothing you can do except making copies.


The optimistic answer assumes they don't want to change the data and you only need to protect them from making mistakes. Now that is possible:

Don't give them any setters. You did not say what your data looks like so I can give you only a vague description:

Do not expose the setters. Give them interfaces to your data classes that do not have setters, return collections as IEnumerable<> instead of the modifiable instance they are and so on. Make sure that through the interface they get to your data, your data cannot be modified.

Sign up to request clarification or add additional context in comments.

6 Comments

I added an exemple now, I like the ideas you are exposing, can you concrete a bit ?
@nvoigt someone can easily cast IEnumerable<> back to List<> and they can modify. Base class library has solution to all problems if you try to be optimistic !! :)
@AkashKava This is C#... if you don't make a copy, "evil" people can just use reflection. Non-evil people are fine with IEnumerable. Any solution is not security, just being helpful so it's harder for the user to make mistakes. Casting an IEnumerable to List is not a mistake, it's intentional evil and falls into category one in my view.
@AkashKava And I hate those readonly fakes that .NET uses. They give you an IList and then throw exceptions half the time you actually use it as an IList. That's violating about any guideline I know about programming. Least surprise, ease-of-use, you name it.
@nvoigt, IEnumerable isn't same as IList, as IList has Count property, IList allows random access and IEnumerable allows only sequential access. IList is never necessarily modifiable. It isn't fake, it is good guideline on how to access "Sequentially" and "Randomly" I think they are genuine computing standards. Anyway you be happy with IEnumerable and try to access objects always sequentially and call random access as some violation, purely your choice.
|
1

If you are looking for a const keywork like in C++ to prevent mutability of data then unfortunatly this does not exist.

What you can do is pass immutable classes (classes without data modifying properties or methods). -> Remove the public set; and just use read only methods

Comments

0

Pass AsReadOnly() as parameters, no one can modify it.

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

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

Call as...

 SomeMethod( myList.AsReadOnly() ); 

So you can create class,

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.