1

If I change the access modifier of the static method within a public class from internal to public, will it break the external assembles which call the method?

NOTES: the internal method can be called by an external assembly with the use of InternalsVisibleTo attribute:

[assembly: InternalsVisibleTo("TheExternalAssembly")]    
namespace TheAssemblyWithInternalMethod 
dingx
  • 1,621
  • 3
  • 20
  • 38
  • Short answer: no. Why would it, unless the external assembly does some reflection to call methods, etc.? – Wai Ha Lee Jan 21 '16 at 11:06
  • @DingxinXu from `internal` to `public` or vice versa ? – tchelidze Jan 21 '16 at 11:06
  • Related: "[*Is it a breaking change that modifying the access modifier of a public property?*](http://stackoverflow.com/q/8580589/1364007)" - but this is not for `static` members. – Wai Ha Lee Jan 21 '16 at 11:11
  • " the internal method can be called by an external assembly with the use of InternalsVisibleTo attribute". This isn't relevant to your question. Leaving aside the fact that this should be treated as a "do not use" feature, `TheExternalAssembly` would already effectively see any internal static methods as public. – David Arno Jan 21 '16 at 12:08
  • @DavidArno yes, i agree that this should be treat as "do not use", but actually, i've already seen it in the production code... – dingx Jan 21 '16 at 12:14

4 Answers4

3

It is possible.

Imagine this shared library code:

namespace SharedLibrary
{

    public class SharedLibraryClassOne
    {
        public static void PotentialCollisionMethod()
        {
        }

        internal static void SharedLibraryMethodTwo()
        {
        }
    }

    public class SharedLibraryClassTwo
    {
        internal static void PotentialCollisionMethod() 
        {
        }

        public static void SharedLibraryMethodThree()
        {
        }
    }
}

Here is a console app that links to the library:

using static SharedLibrary.SharedLibraryClassOne;
using static SharedLibrary.SharedLibraryClassTwo;

namespace StackOverflowChallenge20160121
{
    class Program
    {
        static void Main(string[] args)
        {
            PotentialCollisionMethod(); // Invokes SharedLibraryClassOne.PotentialCollisionMethod
            SharedLibraryMethodThree();
        }
    }
}

This all compiles. But, if I change SharedLibraryClassTwo.PotentialCollisionMethod from internal to public, my dependent application no longer compiles.

Simply by making an internal method public, I get the following error in previously compiling code:

error CS0121: The call is ambiguous between the following methods or properties: 'SharedLibraryClassOne.PotentialCollisionMethod()' and 'SharedLibraryClassTwo.PotentialCollisionMethod()'

Andrew Shepherd
  • 44,254
  • 30
  • 139
  • 205
  • 1
    Nice catch. To whose who answered `No` without thinking. – Sinatr Jan 21 '16 at 11:25
  • Admittedly, this is a breaking change, but relies on using C# 6.0 functionality. Can you think of a breaking change for C# 5.0? – Wai Ha Lee Jan 21 '16 at 11:31
  • @WaiHaLee, you say " but relies on using C# 6.0 functionality" as if C# 6.0 is somehow non-standard. It's the current version of C# 6. What is the relevance of whether it's a breaking change for older versions? – David Arno Jan 21 '16 at 11:59
  • I'm not saying it's non-standard or that your answer is somehow not valid for using C# 6.0; I was more curious than trying to invalidate your answer. – Wai Ha Lee Jan 21 '16 at 12:31
  • @Sinatr Initially, the OP was not mentioning, that internal methods are published by this creepy workaround. So *NO* was the right answer till he gave the additional info. – DHN Jan 22 '16 at 10:10
  • 1
    @DHN - This example fails regardless of the `InternalsVisibleTo` attribute. – Andrew Shepherd Jan 22 '16 at 10:22
  • @AndrewShepherd - Interesting by thinking about it again, you're right. It's not related to the creepy workaround. Anyway, one good reason more to avoid *static* methods, when ever possible. +1 - Thanks for the hint. – DHN Jan 22 '16 at 15:35
  • @DHN I find `static` methods extremely useful. It think the lesson from this whole exercise is "No matter how much you think about it, your change might break something somewhere" – Andrew Shepherd Jan 22 '16 at 21:55
  • @AndrewShepherd I agree, there are scenario in which they are good and the best approach. E.g. (the only good reason, if you ask me) `ExtensionMethods`... the rest should be implemented by using the OO approach. Of course, there are more scenarios, but if I can decide between a `class` or a `static` method, I would always go with the class. – DHN Jan 25 '16 at 12:25
1

Errr... NO? If it's internal, there are no external callers yet. To them, it looks like a method was added, which should be a non-breaking change.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
1

Uhm, as internal is already saying. The method cannot be accessed from other assemblies. Some additional info.

So no, it won't break anything. It will offer new opportunities.

DHN
  • 4,807
  • 3
  • 31
  • 45
  • actually, the internal can be called by external callers, see my new updates – dingx Jan 21 '16 at 12:06
  • @DingxinXu Uh, if you ask me, you should redesign. If it's necessary to use such creepy approaches...then it's broken and won't last long. – DHN Jan 22 '16 at 10:12
-1

No it wont break while changing from internal to public. If it was vice versa there is a higher probability of breaking the code. Your could refer to Jeffrey Richter book Clr via C# where its clearly mentioning of it. "make the class internal unless I want the class to be publicly exposed outside of my assembly" so hence no problem

Maxymus
  • 1,460
  • 2
  • 14
  • 22