0

Ok so let's say that I have a data container class

public class DataContainer {
      public Person person;
}

and we already create an instance of this class

DataContainer dataContainer = new DataContainer();
dataContainer.Person = new Person("Smith");

and we try to pass it in a method that we want to be able to only read the container and not modified

public void ExampleMethod(in DataContainer dataContainer){
   dataConainer.Person.name = "blablabla" //we don't want to be able to do that
   dataContainer = new DataContainer(); // this is not possible because of in keyword
}

I tried the in keyword but it doesn't have any effect on prohibiting changes on container...

P.S. : convert the container into a struct is no solution because it will become immutable

Xrs
  • 31
  • 1
  • 5
  • 2
    That's not possible in C#. You can't have objects appear immutable in some contexts and mutable in others. I'd recommend making the field itself readonly, initialize it through its constructor, and accept immutable semantics everywhere. – Etienne de Martel Mar 31 '20 at 21:18
  • 1
    You could make two interfaces: `IImmutablePerson` and `IMutablePerson` (examples) and have your person class implement both. For methods that are not supposed to make changes, use the immutable contract. – AndreasHassing Mar 31 '20 at 21:23
  • @EtiennedeMartel The issue here is that I want other classes to be able to change data from the container , so a read-only field it doesn't sound good... Maybe a getters and setters could do the work... is it possible to detect who is getting the property? to restrict access from there? – Xrs Mar 31 '20 at 21:23

1 Answers1

1

If you don't want to be able to modify the Person.Name, then you could simply use encapsulation.

I would design the Person class in the following way:

class Person
{
    public Person(string name)
    {
        Name = name;
    }

    public string Name { get; }
}

If this doesn't help, then the only other approach I see is to pass a DTO to ExampleMethod (which can be easily created using Automapper).

var dto = _mapper.Map<DataContainerDto>(dataContainer);
ExampleMethod(dto);

...

public void ExampleMethod(DataContainerDto dataContainer)
{
    // Nobody cares if I modify it,
    // because the original dataContainer reamains intact
    dataConainer.Person.name = "blablabla";
}
Emil Terman
  • 526
  • 4
  • 22
  • that's looks good! actually maybe is what I am looking for... so I am going to give it a try! thanks a lot! – Xrs Mar 31 '20 at 21:39