Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# why must conversion operator must be declared static and public?

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 accessibilitycompiler 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?

like image 916
Philip Pittle Avatar asked Jul 28 '14 18:07

Philip Pittle


1 Answers

It is specified in §10.10:

The following rules apply to all operator declarations:

  • An operator declaration must include both a public and a static 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.

like image 135
p.s.w.g Avatar answered Oct 30 '22 01:10

p.s.w.g