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?
Related
i find it hard to understand exactly what method hiding does.
can somebody please explain me what is going on 'behind the scenes' while using method hiding?
class Base
{
public virtual void OverrideMethod()
{
Console.WriteLine("Base.OverrideMethod");
}
public virtual void HideMethod()
{
Console.WriteLine("Base.HideMethod");
}
}
class Derived:Base
{
public override void OverrideMethod()
{
Console.WriteLine("Derived.OverrideMethod");
}
public new void HideMethod()
{
Console.WriteLine("Derived.HideMethod");
}
}
(1) what does this really do?
Base x=new Derived();
(2) what does these really do?
x.OverrideMethod();
x.HideMethod();
thank you in advance :)
There is hiding and there is overriding. Both are opposites. Personally I keep forgetting hiding aside from thinking "this is not overriding, better not to mix those up". I can not remember a single case where I used it. If I ever can not override, I just encapsulate rather then deal with hiding. So it might well be one of those things someone thought up way back, but never quite took tracktion.
Overriding changes the implementation. It must be explicitly allowed by the baseclass (virtual). It must explicitly be done by the derived class. But in turn the override takes precedence even if class is cast to a base type. Example: Object.ToString(). Code like Console.WriteLine has overloads that just accept a bunch of Objects. But since you can not print Objects, it jsut calls it's ToString() Method.
Hiding does not change the Implementation. It only hides it. As long as you do not cast it to a more basic type, you will have the Hiding Implementation hide the baseclass one. But once you cast down, the baseclass implementation asserts itself. In turn no "allowance" is nessesary.
One thing i need to be clear. When using inheritance i can override a method without using any virtual or override keyword. My program also running and giving correct output. Then why do we have override concept even though we have inheritance. How it differs?
here is my code
class InheritanceDemo
{
public void Mymeth()
{
Console.WriteLine("this is base");
}
}
class A1 : InheritanceDemo
{
public void Mymeth()
{
Console.WriteLine("this is derived");
}
}
Main method:
static void Main(string[] args)
{
InheritanceDemo a = new A1();
A1 b = new A1();
a.Mymeth();
b.Mymeth();
}
output:
this is base
this is derived
Function overriding is needed when the derived class function has to do more or different job than the base class function.
These concepts becomes important in large scale application where problem is big so, u first create an abstract class (which just gives the ideas about how things might be rather than the direct implementation). These Abstract class can contain virtual methods (member functions) that any member of group working on has to implement (as virtual methods have to be defined in the derived class).
I think u got my point... :)
Why do you think the output is "correct"? With inheritance you want to call the correct inherited function and not a method in your base class. And that's what you define with virtual/override.
When you compiled this you should have got a warning CS0108.
Do not ignore warnings. Indeed, if you can set your compilation to error rather than warn. Warnings are generally a sign that you've done something bad or at best unclear. They aren't errors because you might have a good reason for doing something that looks bad or unclear at first look, but in the case of hiding instead of overriding we have new.
What you have here is not an override, though as you seem to expect, generally what you would want here is an override. That's part of why this code produces a compiler warning.
My program also running and giving correct output
Maybe it's correct, but it's not correct if you expected an override. If it was overriding you should have "this is derived" output by both.
If it is correct, it's a bad design, because people generally expect overrides. You can stop the warning by changing A1.Mymeth to be defined as public new void Mymeth() which is a way to flag "I really meant to do this thing that looks wrong", but if you have to explain yourself, that's a bad sign. Hiding methods is generally only to be done when someone changing a base class under you forces your hand, you need to match names due to some sort of interoperability and a small number of other very rare cases.
Say I have an abstract parent class called "Parent" that implements a method called "DisplayTitle". I want this method to be the same for each subclass that inherits "Parent" - I would like a compile error if a subclass attempts to implement their own "DisplayTitle" method. How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#. I've been messing around with "sealed" and "override", but I can't get the behavior that I'm looking for.
For example, in this code:
using System;
namespace ConsoleApplication1
{
class Parent
{
public void DisplayTitle() { Console.WriteLine("Parent's Title"); }
}
class ChildSubclass : Parent
{
public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title");
}
static void Main(string[] args)
{
ChildSubclass myChild = new ChildSubclass();
myChild.DisplayTitle();
Console.ReadLine();
}
}
}
I'd like to receive a compile error saying that the "ChildSubClass" can't override "DisplayTitle". I currently get a warning - but it seems like this is something that I should be able to do and I don't know the proper attributes to label the method.
How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#.
The rough equivalent is sealed in C#, but you normally only need it for virtual methods - and your DisplayTitle method isn't virtual.
It's important to note that ChildSubclass isn't overriding DisplayTitle - it's hiding it. Any code which only uses references to Parent won't end up calling that implementation.
Note that with the code as-is, you should get a compile-time warning advising you to add the new modifier to the method in ChildSubclass:
public new void DisplayTitle() { ... }
You can't stop derived classes from hiding existing methods, other than by sealing the class itself to prevent the creation of a derived class entirely... but callers which don't use the derived type directly won't care.
What's your real concern here? Accidental misuse, or deliberate problems?
EDIT: Note that the warning for your sample code would be something like:
Test.cs(12,19): warning CS0108:
'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited
member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword
if hiding was intended.
I suggest you turn warnings into errors, and then it's harder to ignore them :)
A derived class cannot override your method, you didn't declare it virtual. Note how that's very different in C# compared to Java, all methods are virtual in Java. In C# you must explicitly use the keyword.
A derived class can hide your method by using the same name again. This is probably the compile warning you are talking about. Using the new keyword suppresses the warning. This method does not in any way override your original method, your base class code always calls the original method, not the one in the derived class.
Use the sealed modifier to prevent subclasses from overriding your classes, properties, or methods. What isn't working when you use sealed?
http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
I'm fairly certain that what you want is not possible in C# using method modifier keywords.
Sealed only applies when overriding a virtual method in an ancestor class, which then prevent further overriding.
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".
This question really is kinda pointless, but I'm just curious:
This:
public sealed class MyClass
{
protected void MyMethod(){}
}
compiles, but gives a warning
while This:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
doesn't compile. Just out of sheer curiosity, is there a reason for this?
virtual is used to declare a method/property "override-able".
sealed is used to declare that class cannot be inherited from.
So a virtual method in a sealed class could never be overridden, as the class could never be inherited from. It just doesn't make sense.
protected affects access to a member, it does not declare it "override-able" as virtual does (though it is often used in that manner) and is accordingly not contradictory.
The only reason I can think of is that sometimes you would need to write protected methods to override other protected methods. The language could have been designed to allow this:
protected override void Foo()
but not this
protected void Foo()
but that might have been seen to be a little hard to follow - it's the absence of override which makes it useless, whereas in the case of
public virtual void Foo()
it's the presence of virtual that is useless. The presence of something "wrong" is probably easier to understand than the absence of something useful.
In this case, being virtual may also have performance implications, whereas making something protected instead of private probably doesn't - so it's a bit more severe.
These are just guesses though really - if we're really lucky, Eric Lippert will give a more definitive answer. He's the one you want, not me :)
Best answer: treat warnings as errors and they're equivalent anyway ;)
I can't see a good reason for this. The protected MyMethod can be called from MyClass, but will never be called from a derived class (because MyClass is sealed). The virtual version is also allowed to be called directly from MyClass, but it is illegal for the method to have an override because you can't derive a class from MyClass...
A sealed class can have protected members via inheritance.
When a method is part of a class, it doesn't matter how that method got there.
In the first case, with the protected method on the sealed class, its the same as if the sealed class inherited a protected method. So it compiles.
Out of curiosity, what exactly is the warning given?
The error is:
CS0549: 'function' is a new virtual member in sealed class 'class'.
First of all, despite the fact that it doesn't really make sense to include new protected or virtual members in a sealed class, the CLI¹ does allow it. The CLI also allows calling members of a sealed class using the callvirt IL instruction, even though a compiler could freely replace it with the call instruction.
Currently, I can't find anything in ECMA-334 (C# Language Specification) that requires the compiler emit the above error. It appears like a Microsoft's implementation added the error just because it doesn't make sense to include new virtual members in a sealed class.
¹The CLI is a virtual machine, and the C# compiler emits byte code that runs on it. Almost any concept that's illegal in the CLI is also illegal in C# for that reason - but this is a case where C# does a little extra (not that it's a problem).
Edit: It seems to posts getting marked up are explaining why it doesn't make sense to write code like that in the OP. But regarding what rule made it a compiler error they appear to be wrong.
A sealed class cannot be sub-classed, therefore virtual is not an option. Thus error.
This first is a bit silly but valid, thus warning.
I'd guess the compiler does some optimizations with sealed classes that are impossible if you have a virtual method declared - "not having a vtable" seems a likely candidate.
That's just a guess, though.
As sealed When applied to a class, the sealed modifier prevents other classes from inheriting from it.
here i am trying to explain you one by one:
public sealed class MyClass
{
protected void MyMethod(){}
}
it gives you warning because practically it make no sense because after declaring a class as sealed you can't inherits it and as your method is protected so you can't access it outside the class using it's object(and keep also in mind that you can't create a child class of this so you can't use this method by that trick also).So practically it makes no sense to making it protected so compiler gives you a warning but if you make it as public or internal then it will not gives you error because it's useful in that case.
now the second one:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
as you sealed you class and now you are making your method as virtual so indirectly you are giving a offer to someone to override it and that can be only possible by inheritance and here comes the issue.That you class is sealed so you can't perform inheritance with this class.so that's why with virtual it gives error.
i hope it will help you to understand.
for reference http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
Declaring a new protected member implies an intent to share that member with descendent classes. A sealed class cannot have descendents, so declaring a new protected member is a bit of an oxymoron, just as declaring a new virtual method in a sealed class.
As for why virtual produces an error while protected only produces a warning, I can only speculate that perhaps it has to do with the fact that new virtual methods require the compiler to build data structures for the type (a vtable), whereas new protected members only have an access flag set - no new data structure. If the compiler is prohibited from creating a vtable for a sealed class, what should it do if it encounters a new virtual method? Fail the compile. A new protected method in a sealed class is pointless but doesn't required the compiler to venture into forbidden territory.