My explanation, with some conjecture on my side:
There's an old rule that if you'd rather not implement an interface member as a public class member, then you must use explicit implementation. This allows to make prescribed interface members "hard to access" because in your implementation they are not suitable for public usage. Note that even then the implementation remains public.
This also seems to apply to interface parts that can now declare themselves with less-than-public visibility, it now seems to be: any member of an interface that *isn't fully public* or that you *don't want to implement as public* must use explicit implementation. Note: I have no source for this, I distilled it from what I see is happening.
Since your property is only "half public", apparently all of it falls under that rule.
Then there is another rule, quoting from the documentation:
An explicit interface implementation doesn't have an access modifier since it isn't accessible as a member of the type it's defined in. Instead, it's only accessible when called through an instance of the interface.
This explains why as soon as you use explicit implementation (forced or not), you can't add access modifiers of your own because the interface defines the applicable access modifiers (with public being the default if omitted).
Consequences of doing this
To access even the public getter, all client code needs to use IFoo:
var f = new Foo(); var x = ((IFoo)f).Bar; // works
IFoo f = new Foo(); var x = f.Bar; // works
var x = new Foo().Bar; // does not compile
It's up to you to decide if it is worth to force this requirement onto your callers.
If needed then I see two ways to avoid that requirement, first way means leaving the internal setter out of the interface and only put it in Foo, but then code using the setter must use Foo as the variable type, it can't use IFoo, while code using the getter can do whatever it likes:
public interface IFoo
{
public string Bar { get; } // no setter (and you can omit `public`)
}
public class Foo : IFoo
{
public string Bar { get; internal set; } // add internal setter as class member
}
Second way, having an internal void SetBar(string value) in the interface, now all code using SetBar() must use IFoo as the variable type, and code using the getter can do whatever it likes:
public interface IFoo
{
public string Bar { get; }
internal void SetBar(string value);
}
public class Foo : IFoo
{
public string Bar { get; private set; } // add private setter as class member
void IFoo.SetBar(string value) { Bar = value; } // use private setter
}