I have a C# class with a field that needs to be visible from outside the class, but should be changed only from within the class. However, the problem is that the field is updated via a public mutator method, not directly (or by a property):
public class FirstClass
{
public SecondClass TheField {get; private set;}
public FirstClass()
{
TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
TheField.Update(/*parameters*/);
// ...
}
}
public class SecondClass
{
// some fields
public SecondClass() { }
public void Update(/*parameters*/)
{
// do something
}
}
In other words, I would like the method Update() to be accessible only from within FirstClass.
Few possible solutions and the reasons why I'm not safisfied with them:
Is there a way to do this?
A basic implementation of @aquaraga's answer, but using interfaces instead:
public interface ISecond
{
// some properties
}
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : ISecond
{
// some properties
public void Update(/*parameters*/)
{
// do something
}
}
}
Essentially, expose a public interface that has all the accessible members but no Update
method. Employ a private nested class which has an Update
method, but otherwise not accessible to calling code and expose it as the interface, not as the class.
Some sample usage:
FirstClass myFirst = ...
myFirst.SomeMethod(); //updates ok!
Console.WriteLine(myFirst.TheField.PropertyA); //can access properties of ISecond
myFirst.TheField.Update(); //compiler error!
One point is that you mention using "some fields"; as an interface you wouldn't be able to have fields but properties instead. I'm not sure if that's a deal breaker or not for you.
EDIT: You mentioned your intent to reuse the SecondClass
and minimize code duplication. One quick fix might be to declare some abstract
class, a protected Update
method, employ an internal
constructor (so other assemblies can't inherit from it), then expose the Update
call with a minimal implementation:
public abstract class SecondClassBase : ISecond
{
// some properties
internal SecondClassBase()
{
}
protected void Update(/*parameters*/)
{
// do something
}
}
Then in your FirstClass
, nothing changes except the nested class:
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : SecondClassBase
{
public new void Update(/*parameters*/)
{
base.Update(/*parameters*/);
}
}
}
Still some code duplication, but all you need to do now is copy/paste the code; no need to redeclare the properties or the Update
logic for each implementation of FirstClass
. You could also rename the new Update
method to something else to avoid method hiding, but I figured I'd keep the same calling signature you had before.