The only way to do it is to create a method in ClassA which sets the property
public class ClassA
{
public string ID { get; private set; } = "default id";
public void SetID(string id)
{
ID = id;
}
}
public class ClassB
{
private ClassA _classA = new ClassA();
public ClassB()
{
Debug.WriteLine(_classA.ID);
_classA.SetID("some id");
Debug.WriteLine(_classA.ID);
}
}
Then call that method from ClassB.
This approach can be used if you want to perform some form or shape of validation or perhaps adding dynamically constructed values to the property.
You could also use a "smart property" in those cases but then again that is a controversial topic...
And sometimes you are just not allowed to change the interface of a class and then you have to find some approach.
As mentioned in the comments this defeats the purpose of the private setter.
But then again there might be some scenarios in which you want to use this approach.
In any case this answers the question.