Why use a public method in an internal class? - c#

There is a lot of code in one of our projects that looks like this:
internal static class Extensions
{
public static string AddFoo(this string s)
{
if (s == null)
{
return "Foo";
}
return $({s}Foo);
}
}
Is there any explicit reason to do this other than "it is easier to make the type public later?"
I suspect it only matters in very strange edge cases (reflection in Silverlight) or not at all.

UPDATE: This question was the subject of my blog in September 2014. Thanks for the great question!
There is considerable debate on this question even within the compiler team itself.
First off, it's wise to understand the rules. A public member of a class or struct is a member that is accessible to anything that can access the containing type. So a public member of an internal class is effectively internal.
So now, given an internal class, should its members that you wish to access in the assembly be marked as public or internal?
My opinion is: mark such members as public.
I use "public" to mean "this member is not an implementation detail". A protected member is an implementation detail; there is something about it that is going to be needed to make a derived class work. An internal member is an implementation detail; something else internal to this assembly needs the member in order to work correctly. A public member says "this member represents the key, documented functionality provided by this object."
Basically, my attitude is: suppose I decided to make this internal class into a public class. In order to do that, I want to change exactly one thing: the accessibility of the class. If turning an internal class into a public class means that I have to also turn an internal member into a public member, then that member was part of the public surface area of the class, and it should have been public in the first place.
Other people disagree. There is a contingent that says that they want to be able to glance at the declaration of a member and immediately know whether it is going to be called only from internal code.
Unfortunately, that doesn't always work out nicely; for example, an internal class that implements an internal interface still has to have the implementing members marked as public, because they are part of the public surface of the class.

If the class is internal, it doesn't matter from an accessibility standpoint whether you mark a method internal or public. However it is still good to use the type you would use if the class were public.
While some have said that this eases transitions from internal to public. It also serves as part of the description of the method. Internal methods typically are considered unsafe for unfettered access, while public methods are considered to be (mostly) free game.
By using internal or public as you would in a public class, you ensure that you are communicating what style of access is expected, while also easing the work required to make the class public in the future.

I suspect that "it is easier to make the type public later?" is it.
The scoping rules mean that the method will only be visible as internal - so it really doesn't matter whether the methods are marked public or internal.
One possibility that comes to mind is that the class was public and was later changed to internal and the developer didn't bother to change all the method accessibility modifiers.

I often mark my methods in internal classes public instead of internal as a) it doesn't really matter and b) I use internal to indicate that the method is internal on purpose (there is some reason why I don't want to expose this method in a public class. Therefore, if I have an internal method I really have to understand the reason why it's internal before changing it to public whereas if I am dealing with a public method in an internal class I really have to think about why the class is internal as opposed to why each method is internal.

In some cases, it may also be that the internal type implements a public interface which would mean that any methods defined on that interface would still need to be declared as public.

It's the same, the public method will be really marked as internal since it's inside a internal class, but it has an advantaje(as you guested), if you want to mark the class as public, you have to change fewer code.

For the same reason as using public methods in any other class - so that they're public to the outside of the containing type.
Type's access modifier has exactly zero to do with its members' access modifiers. The two decisions are made completely independently.
Just because certain combinations of type and members' modifiers produce seemingly (or as others call it "effectively") the same result doesn't mean they're semantically the same.
Local access modifier of a an entity (as declared in code) and its global effective access level (as evaluated through the chain of containment) are completely different things, too. An open office inside of a locked building is still open, even though you can't really enter it from the street.
Don't think of the end effect. Think of what you need locally, first.
Public's Public: classic situation.
Public's Internal: type is public but you want some semi-legal access in the assembly to do some hacky-wacky stuff.
Internal's Public: you hide the whole type but within the assembly it has a classic public surface
Internal's Internal: I can't think of any real world example. Perhaps something soon to become public's internal?
Internal's Public vs Internal's Internal is a false dilemma. The two have completely different meaning and should be used each in their own set of situations, non-overlapping.

internal says the member can only be accessed from within the same assembly. Other classes in that assembly can access the internal public member, but would not be able to access a private or protected member, internal or not.

I actually struggled with this today. Until now I would have said that methods should all be marked with internal if the class was internal and would have considered anything else simply bad coding or laziness, specially in enterprise development; however, I had to sub class a public class and override one of it's methods:
internal class SslStreamEx : System.Net.Security.SslStream
{
public override void Close()
{
try
{
// Send close_notify manually
}
finally
{
base.Close();
}
}
}
The method MUST be public and it got me thinking that there's really no logical point to setting methods as internal unless they really must be, as Eric Lippert said.
Until now I've never really stopped to think about it, I just accepted it, but after reading Eric's post it really got me thinking and after a lot of deliberating it makes a lot of sense.

There does be a difference.
In our project we have made a lot of classes internal, but we do unit test in another assembly and in our assembly info we used InternalsVisibleTo to allow the UnitTest assembly to call the internal classes.
I've noticed if internal class has an internal constructor we are not able to create instance using Activator.CreateInstance in the unit test assembly for some reason. But if we change the constructor to public but class is still internal, it works fine.
But I guess this is a very rare case (Like Eric said in the original post: Reflection).

I think I have an additional opinion on this. At first, I was wondering about how it makes sense to declare something to public in an internal class. Then I have ended up here, reading that it could be good if you later decide to change the class to public. True. So, a pattern formed in my mind: If it does not change the current behavior, then be permissive, and allow things that does not makes sense (and does not hurt) in the current state of code, but later it would, if you change the declaration of the class.
Like this:
public sealed class MyCurrentlySealedClass
{
protected void MyCurretlyPrivateMethod()
{
}
}
According to the "pattern" I have mentioned above, this should be perfectly fine. It follows the same idea. It behaves as a private method, since you can not inherit the class. But if you delete the sealed constraint, it is still valid: the inherited classes can see this method, which is absolutely what I wanted to achieve. But you get a warning: CS0628, or CA1047. Both of them is about do not declare protected members in a sealed class. Moreover, I have found full agreement, about that it is senseless: 'Protected member in sealed class' warning (a singleton class)
So after this warning and the discussion linked, I have decided to make everything internal or less, in an internal class, because it conforms more that kind of thinking, and we don't mix different "patterns".

Related

'Protected member in sealed class' warning (a singleton class)

I've implemented a singleton class and keep getting the warning that a method I'm writing is a 'new protected member declared in a seal class.' It's not affecting the build but I don't really want to ignore the warning in case it causes problems later on? I understand a sealed class is a class that cannot be inherited - so it's methods cannot be overridden, but I still don't get why the following code would give me the warning (is it due to the use of the singleton design?):
namespace WPFSurfaceApp
{
public sealed class PresentationManager
{
PresentationManager()
{
}
protected void MethodName()
{
}
public static PresentationManager Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly PresentationManager instance = new PresentationManager();
}
}
EDIT: The warning is regarding MethodName() method.
EDIT: Change public void MethodName() to protected void MethodName()
The warning is because protected does not make sense in a class that can't be inherited from. It will logically be exactly the same as private for a sealed class.
It's not an error, per se, but the compiler is trying to draw your attention to the fact that making it protected instead of private will provide you no benefit and may not be doing what you intended (if you intended it to be visible to a sub-class, which can't exist in a sealed class).
So, yes, you can safely ignore it, but it's logically inconsistent to have protected members in a sealed class.
MSDN Entry for Compiler Warning CS0628
It is obvious because it doesn't make any sense. What will be use of protected member if class cant be inherited
As MSDN Says
Types declare protected members so that inheriting types can access or
override the member. By definition, you cannot inherit from a sealed
type, which means that protected methods on sealed types cannot be
called.
Think about when you review code yourself. You see something that makes no sense as far as you can see. There are a few likely possibilities:
The developer has done something foolish.
The developer has done something too clever for its purpose to be obvious to you.
The developer did something reasonable that no longer makes sense due to changes that took place in the mean time.
The developer did something that makes no sense yet, but will if a planned change happens.
In the first case, they should fix it.
In the second case, they should document it.
In the third case, they should change it; it'll make little practical difference but the code will make more sense and it may have some minor performance benefit.
In the fourth case, they should document it for the time being, and either make that change or back out of it sooner rather than later.
Either way, you would want to discuss it with them.
It's the same here, it makes no sense to add a protected member to a sealed class. I've no idea why you did it, and can't decide which of the four cases above applies, but one of them does. The warning highlights this. Do whichever of the four actions applies according to which of the four cases is in effect.
I say your are playing with C#. Seriously !!
In a static class, it is said that we can't declare protected members as static classes cannot be instantiated. In fact, when we write protected members in static classes it will throw an error during the build.
In a sealed class, it will throw a warning during the build. I guess like static classes, sealed classes should also give an ERROR and not a WARNING. If this difference should be there then why?

Restricting access property in subclass

I have a class with a public property, that I want to restrict access to _for_some_modules_.
(The modules that use this class reside in different assemblies, so internal does not help.)
My first thought was to subclass, and make the derived property accessor private or protected, but this is not possible. The derived property has to have the same access rights. (See http://msdn.microsoft.com/en-us/library/75e8y5dd.aspx)
Any suggestions? I assume it is a common task to make a more restricted variant of a class?
Thanks!
You can use the InternalsVisibleToAttribute to make the internal members of the class visible to other assemblies (as many as you like). The documentation page has an example.
I assume it is a common task to make a
more restricted variant of a class?
This is not a common task since it violates the Liskov substitution principle - you can't use the sub class the same way as you would use the base class in regards to the property you restrict access to. You should consider refactoring your class hierarchy.
You could solve the problem through composition - make the class A internal only and write a public wrapper class that has a member of type A and delegates and controls access to the A's properties / methods.
Making more restricted subclasses is actually not common because it would break consumers of the base class that assumed they had access to the public members. In general, your classes should start out restrictive and get less so as they specialize, not vice-versa.
The concept you're looking for is called a "friend" class in other languages, but C# (purposely) doesn't implement them. The InternalsVisibleToAttribte is as close as it gets, but that is applied at the assembly level, so it may not work for you.
Without more information on why you are trying to restrict access this way, it's hard to give any good general-purpose alternatives. The access modifiers like public/private/etc aren't designed to be a security mechanism, since Reflection will get you access to read/write everything regardless. They're more of a hint to the consumers as to what is safe to use -- public members will usually remain stable across new versions, while private (implementation-detail) members are more likely to change.
You can always do something like this:
class MyBaseClass
{
protected string MyRestrictedProperty { get; set; }
}
class MyClass : MyBaseClass
{
public string MyPublicProperty
{
get { return MyRestrictedProperty; }
set { MyRestrictedProperty = value; }
}
}

internal vs public in C#

I want to know the difference between the public and internal visibility modifiers.
When should we use internal on a class and when public? I am confused with when a method should be public or internal.
I read that internal can be accessed through the assembly, while public can also be used through the assembly. Then where does the difference lie?
public is visible from wherever.
internal is visible only within an assembly.
You tend to use internal only to protect internal APIs. For example, you could expose several overloads of a method:
public int Add(int x, int y)
public int Add(int x,int y, int z)
Both of which call the internal method:
internal int Add(int[] numbers)
You can then put a lot of sophistication on a method, but "protect" it using facade methods that may help the programmer to call the method correctly. (The implementation method with the array parameter may have an arbitrary limit of values, for example.)
Also worth noting that using Reflection, any and all methods are callable regardless of their visibility. Another "hack" to control/gain access to internally hidden APIs.
internal is useful when you want to declare a member or type inside a DLL, not outside that.
Normally, when you declare a member as public, you can access that from other DLLs. But, if you need to declare something to be public just inside your class library, you can declare it as internal.
In formal definition: internal members are visible just inside the current assembly.
internal is also useful when writing unit tests. The InternalsVisibleTo attribute lets your test assembly access internal methods in your code assembly. That is, you can test methods that appear private to the outside world without using reflection.
Public can also be accessed outside of the assembly. So when you have a class that shouldn't be accessed every class in the assembly should be able to access it, then internal is the right thing. If you need outside access, use public.
Also, properties marked as internal will throw a BindingExpression path error if used for DataBinding in WPF. So those have to be public in order to work properly, even when the DataBinding takes place within the same assembly.
In general, public methods should meet very high standards for robustness (not crashing or corrupting data due to bad input) and security awareness (not allowing unexpected input to trigger an exploit). But for internal, protected, and private methods, it will often be reasonable to follow more relaxed standards, since one has full control over what inputs each method can receive.
Because parameters passed to a public method (possibly from an external source) are considered less trustworthy than parameters received from within one's own assembly, methods marked as public are often treated differently by code analyzers than otherwise identical methods marked as internal. Just as an example, with a public method the analyzer may warn you to check that the method's parameters are not null. With internal methods, it may be possible to configure the analyzer to be less strict about null checking. Or the analyzer may be able to determine on its own, by doing flow analysis of all the source files for the assembly, that null will never be passed to the particular method as an argument, and thus determine there is no need to check if the parameter is null. There are many other examples of analyzers treating public and internal methods differently.
By correctly marking classes, methods, properties, fields, interfaces, etc. with the correct access modifiers, you correctly signal to code analyzers your intent, and then in return the analyzer can give you more relevant warning messages and advice.
In a very simple language:
Internal : you will only able to access within a assembly.
for ex: if you have created a AccountService.csproj with internal class
public interface IAccount{
int TotalAmount(long accountID);
}
internal class Account:IAccount{
public int TotalAmount(long accountID){
...
}
}
public class Customer{
public long accountID {get;set;}
public int GetTotalAmount(){
IAccount account = new Account();
return account.TotalAmount(accountID)
}
}
if you are referring AccountService.csProj to BankService.csProj (BankService.csProj --> AccountService.csproj)
Below are the properties that accessible in BankService.csProj
Customer.GetTotalAmount() -- Accessible
IAccount.TotalAmount() -- Accessible
Account.TotalAmount() -- Not Accessible (as account class is internal)
If you can Reference the assemble from outside , you have scope of Internal and public classes

When defining a class as internal, do you define what would usually be public fields as internal?

When defining a class as internal, do you define what would usually be public fields as internal? Or do you leave them as public? I have a set of classes with public/private methods that I have decided to set as internal. Now, should I change the class' modifier to internal and let the rest of the methods/properties as they are (public/private) or switch them to (internal/private)?
I don't see a big point in changing it to internal, and if by some reason later I want to set them back to public it's going to give a lot of work to have to put them back to public again.
Any other thoughts on this?
I can't see any reason not to leave them as public, as your class won't be visible to outside assemblies anyway. The only case where I think this might matter is when using reflection over that class.
If I have a class that is internal, I leave the class members as public (or protected/private of course if that's what they were). I find that often I have classes that I hope I can keep internal that I end up having to expose eventually and switching all the appropriate members back to public is annoying.
You defnitely shouldn't change private members to internal as that would make them more accessible. There is no need to change public members to internal since nothing outside of the defining assembly will ever be able to get a reference to an internal class anyway.
I think you should give generally members the same visibility as you would if the Type were itself public.
That is, members that are part of the public API should be public, and members that are special-purpose helpers that should only be visible to "friend" classes should be internal.
This means there will be no changes to member visibility if you ever decide to make the Type public.
More importantly, it also documents your intention - anyone reading your code will be able to identify which (if any) members are intended to be internal.
We use internal keyword for members in internal classes, so that the intention is clear. However it fails if one implicitly implement internal interfaces, where the members have to be defined as public. We dont know why and see this as an accidental mistake in the language specification that we have to live with.
Dig around in Reflector for a bit and you'll see that the BCL itself is wildly inconsistent over this. You'll see many internal classes with public members and many others with internal members. Several classes even mix and match the two with no particular rhyme or reason that I'm able to discern.
There is no "right" answer here, but there are a few things you should consider whenever you need to make a decision on this:
internal members cannot implicitly implement an interface, and explicit implementations are always private. So if you want interface members to be accessible through the class instance (the Dispose method of IDisposable is a common one), they need to be public.
Type visibilities can change. You might decide down the road that an internal class has some valuable functionality that you want to make available to the outside. But if you do, then all public members become accessible by everyone. You should decide in advance if this is what you want.
On the other hand, another reason you might make an internal class public is if you decide that you need to subclass it and that the derived classes should be in a different assembly. In this case, some of your internal members should probably be protected internal instead, otherwise derived classes won't have access to members they might need.
In the end, what it all comes down to is writing code to be read and maintained by other people. The modifier internal can mean two very different things to a maintenance programmer:
That it doesn't seem useful to the outside world, but wouldn't actually be harmful either. A typical example would be a utility class that was whipped up in 5 minutes and doesn't do much validation or error checking. In this case, it's OK for someone to make it public as long as they tighten up the code a little and/or document how to use it properly. Make this assumption explicit by making the members public.
That it's actually not safe for outside consumption; it might manipulate some protected state, leave handles or transactions open, etc. In this case, you really want to make the individual methods internal to make it absolutely clear that nobody else should be using this class, ever.
Choose whichever one is appropriate for your scenario.

Is there any constraint to specify the access specifier of members of a class when we have specified access specifier of the class?

Suppose that we have a class named class1.
The class1 has several properties and methods and we have decided to specify the access specifier of class1 as internal.
Now, can we set the access specifier of class1 methods as public?
For your specific question, Class 1 which is declared as internal can have a public method.
Why?
Look at Jon Skeets explanation:
You can certainly mark a class as
internal, but that's different from
making its public members internal.
For instance, suppose you have a class
which implements a public interface.
Even though the class may be internal,
an instance may still "get out of the
assembly" by being returned from a
member in another (public) class. That
instance would have to be referenced
by the interface it implements rather
than the class name itself (as the
class isn't known to the outside
assembly) but the public methods can
still be called.
If the public methods aren't
implementing any interfaces, I suspect
it would only make a difference in a
very few reflection cases which you
may not care about.
community wiki - as credit should go to Jon Skeet
Yes, you can set public on members of internal/private/etc types.
As other replies have noted, external code won't be able to see the properties unless it can see the type - but there are lots of nuances:
if the member is on an interface it will be (essentially) part of the public API
the member might be a public override of a virtual/abstract member - in which case it will truly be publicly visible, but via the base-class (again, similar to interfaces)
But there is a lot of other code in the framework that uses reflection and demands public accessibility:
data binding usually works on the public properties
security checks for partial-trust can be fussy about public members
serialization (for example XmlSerializer) may want public members
etc
So there are still lots of reasons to think about public rather than just internal, even if your code is only referenced by the local assembly.
By rule access specifiers on methods and properties can not be more more accessible than that of the class containing it.
But I've tried this:
internal class Test
{
public string Testing{get;set;}
}
and it compiles without any exception! I think it is okay as the class Test will not be accessible outside the namespace assembly we have declared so public property will not make any difference.
This does not works:
private class Test
{
public string Testing{get;set;}
internal string TestingAgain{get;set;}
}

Categories

Resources