Regarding the following compiler error:
User-defined operator 'Foo.implicit operator Foo(Bar)' must be declared static and public
What is the reason for this? Why must a user-defined conversion operator be public
?
Give the following code, why wouldn't this conversion be legal:
internal class Bar{}
internal class Foo
{
private Bar _myBar;
internal static implicit operator Bar(Foo foo)
{
return foo._myBar;
}
}
I checked the C# Language Spec and the relevant section (10.10.3) didn't mention this requirement. Is it a compiler thing and not a C# / .Net restriction?
To make things weirder, I can make the above conversion operator public
as long as both Foo
and Bar
are internal
, which is odd, because I would think that you couldn't return an internal
object on a public method (although I suppose if the entire class is internal
it wouldn't matter). However, if I make a public
PublicFoo
and keep Bar
internal
then I get an inconsistent accessibility
compiler error:
internal class Bar { }
internal class Foo
{
private Bar _myBar;
/// <summary>
/// No inconsistent accessibility: return type
/// </summary>
public static implicit operator Bar(Foo foo)
{
return foo._myBar;
}
}
public class PublicFoo
{
private Bar _myBar;
/// <summary>
/// Inconsistent accessibility: return type !!
/// </summary>
public static implicit operator Bar(PublicFoo foo)
{
return foo._myBar;
}
}
Summary
Why must user-defined conversions be public?
It is specified in §10.10:
The following rules apply to all operator declarations:
- An operator declaration must include both a
public
and astatic
modifier.
The reason you don't get an 'inconsistent accessibility' error with your first snippet is the same reason you don't get an error when you define a public method on an internal type in general. It's perfectly valid to declare public methods on internal types.
The reason you get an error in the second snippet is because it's not valid to return an internal type in a public method of a public type. These rules apply to any methods, not just operators.
As to why the language designers chose to require conversion operators to be public… I suppose they probably wanted to avoid having too much 'magic' going on with those operators—that is, they didn't want code to function one way inside one assembly and a completely different way inside another assembly without any obvious indication of what was going on. Remember operators are just syntactic sugar. If you want to have a conversion method that's only visible within your assembly, simply define ToBar()
and call it yourself; don't rely on the operators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With