Another approach would be something along these lines. Notice that the getter and setter here specify class B as a key so other classes cannot reach to the inner state of class A.
public class Program
{
public static void Main()
{
var a = new A(29);
var (getter, setter) = A.GetAndSetOnlyForB(a);
Console.WriteLine(getter(new B())); // 29
setter(new B(), 2);
Console.WriteLine(getter(new B())); // 2
getter(new C()); // compile error, cannot do that
setter(new C(), 9); // compile error, cannot do that
}
}
sealed class A
{
private int _hiddenInt;
public A(int hiddenInt)
{
_hiddenInt = hiddenInt;
}
public static (Func<B, int>, Action<B, int>) GetAndSetOnlyForB(A obj)
{
return ((key) => obj._hiddenInt, (key, arg) => { obj._hiddenInt = arg; });
}
}
sealed class B
{
}
sealed class C
{
}
internal
+ properties = safe. – Odontograph