c# abstract methods: internally public and virtual? - c#

Are abstract methods internally public and virtual in c#?
All methods are, by default, private and if an abstract method is private, it will not be available to derived class, yielding the error "virtual or abstract members cannot be private"

I think you are asking a different question than most people think (in other words it seems like you understand what abstract means).
You cannot declare a private abstract method - the compiler issues an error. Both of these classes will not compile:
class Foo
{
private abstract void Bar();
}
class Baz
{
// This one is implicitly private - just like any other
// method declared without an access modifier
abstract void Bah();
}
The compiler is preventing you from declaring a useless method since a private abstract member cannot be used in a derived class and has no implementation (and therefore no use) to the declaring class.
It is important to note that the default access modifier applied to an abstract member by the compiler (if you do not specify one yourself) is still private just like it would be if the method was not abstract.

Abstract is just a way to say: "I am here, but no one has told me what I'm going to do yet." And since no one has implemented that member yet someone must do that. To do that you have to inherit that class, and override that member.
To be able to override something it has to be declared either abstract or virtual, and must at least be accessible to the inheritor, i.e. must be marked protected, internal or public.

Abstract methods cannot be private and are virtual. They must be at least protected.

By virtue of Jon Skeet's argument here (What are the Default Access Modifiers in C#?)
The default access for everything in C# is "the most restricted access you could declare for that member"
It must be "protected"
As pointed out by Pieter default is always private, so:
abstract class Foo
{
abstract void Bar();
}
Gives compiler error
virtual or abstract members cannot be private

Related

Is there a C# equivalent of Java's #Override?

This has been asked before, but I could not get clarity from that answer, that's why I ask again...
Let's use two examples:
class implements interface
class extends an abstract class
My feeling is that with respect to the override keyword, both samples must behave identically. What is the desired goal of override? To prevent a method being dropped in a superclass or interface without being changed in all subclasses or implementing classes. So a compile time code consistency check.
In this C# code, compiling results in error: '....RepositoryContext.getXmlDoc()': no suitable method found to override:
interface IRepositoryContext
{
XmlDocument getXmlDoc();
}
class RepositoryContext : IRepositoryContext
{
private readonly XmlDocument gXmlDoc = new XmlDocument();
public override XmlDocument getXmlDoc() // does not compile
{
return gXmlDoc;
}
}
Whereas in this C# code, compilation works without any errors or warnings:
abstract class RepositoryContextBase
{
public abstract XmlDocument getXmlDoc();
}
class RepositoryContext : RepositoryContextBase
{
private readonly XmlDocument gXmlDoc = new XmlDocument();
public override XmlDocument getXmlDoc()
{
return gXmlDoc;
}
}
Is it a valid assumption that this should not work identically, or is there a way around this, or...?
The override modifier is defined thus:
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.
http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx
The override keyword specifies that the method overrides an existing method implementation, which is why you don't need to specify it when you're implementing an interface directly - there is no such method to override; you're the first to implement it.
When you use the override keyword, you're essentially saying "for this class, call this method instead of the base method." This obviously doesn't apply when there is no such base method (e.g. when you are directly implementing an interface).
For virtual or abstract methods from classes, you need to insert the override keyword or it won't work at all.
For interfaces, there is no equivalent.
However, interface implementations must implement all of their base methods, so forgetting a method will usually give you a compiler error.
This makes it less important.
In the first example it's an interface you're implementing. You can't override something when you're the only implementer in the inheritance chain.
In the second example you've inherited from a concrete implementation and stated that you want to implement the abstract member and the syntax for that (albeit not literally an override as much as an implementation) is the override keyword. However, you are in fact overriding the chain you're a part of because you're implementing it.
So think of the override keyword more in relation to the fact that you're ensuring your implementation gets called instead of the base class when it's called on an instance of the inheritor.
This too explains why you must explicitly call base.Member() inside the override because you've overriden the chain.
Another OO concept to remember is that the same effect can be achieve on methods that aren't abstract or virtual. Members can in fact be hidden and you don't have to specify them with the new keyword.
With that being said it should help abstract for you the idea that these are very much just language features or maybe better said it's just syntax.
In your first example you are implementing an interface. In this case you do not have to specify the override keyword, simply remove it.
Seems like you have a misconception regarding interface implementation vs. inheritance.
Interface implementations are completely different from inheritance. With an interface, you statically (i.e. at compile time) enforce the presence of certain method signatures. Therefore, any keywords like override or the like are just plain wrong in such a context.
Inheritance on the contrary is causing runtime polymorphism through a virtual method table (basically a list of method adresses).
You can see this also from the fact that, in C#, you can implement as many interfaces as you like, whereas multiple inheritance is forbidden.
The reason is that there is a fundamental difference between implementing an interface and overriding a method.
In order to fully implement an interface, you have to provide implementations for all of methods and/or properties but those implementations do not necessarily have to be overrideable in turn. The compiler wants you to be very specific about your intentions when you create a method, because you may have one of a range of behaviours in mind, and it wants to be sure which one you mean.
The override keyword means "I am overriding the base class' implementation with this one". If when implementing an interface, there is no base implementation, then it doesn't apply. You use virtual to indicate an overrideable method with no base implementation, and omit both override and virtual otherwise.
So given this interface:
interface IFoo
{
void Bar();
}
This class implements that interface, and permits classes to inherit from it in turn and override that implementation (since unlike in e.g. Java, methods in C# are not virtual by default):
class Foo : IFoo
{
public virtual void Bar() { ... } // compiles
}
class DerivedFoo : Foo
{
public override void Bar() { ... } // compiles, and may choose to call base.Bar()
}
Whereas this class implements that interface, and does not permit overrides:
class Foo : IFoo
{
public void Bar(); // compiles
}
class DerivedFoo : Foo
{
public override void Bar() { ... } // does NOT compile; Foo.Bar() is not virtual (overrideable)
}
There are in fact more possiblities than that, including:
You can create an abstract base class which implements an interface, but only provide abstract implementations for some/all methods.
You can explicitly implement an interface method
You can seal an overriding method to prevent further overrides
You can create a new method with the same name which is unrelated to the base class' method of that name
There are more details on MSDN.
If you aren't specific enough for the compiler, it will warn you or throw an error.
Update
The reason the compiler complains in the second example above, is that you will not get polymorphic behaviour. That is, if someone has a reference to Foo and calls Bar(), they will get Foo's implementation, not DerivedFoo's. This is because Bar.Foo is not in the virtual method table. Put another way, in C#, the default when compared to Java is that all methods are final unless you say otherwise.
From your comments it sounds like you're trying to get a warning or error in the case where, in my first example above, you then change IFoo by removing the Bar method entirely. (Obviously if you just change the method signature, you'll get a suitable compile error as you'd hope.)
You can achieve this by explicitly implementing the method:
class Foo : IFoo
{
void IFoo.Bar() { ... }
}
Then if the interface changes, you will get a compile error. However, this means derived classes can no longer override Foo's implementation; if you want that behaviour as well, you need:
class Foo : IFoo
{
void IFoo.Bar() { ... }
protected /* or public */ virtual void Bar()
{
IFoo foo = this; // declare rather than cast, to get compile error not runtime exception
foo.Bar();
}
}
You will still get compile errors if you remove the method, both from your explicit and other implementation.
Bear in mind that the explicit implementation is only available to callers with a reference to an IFoo, not a Foo. But if as in the above code you do add a public method which, for example, delegates to the explicit IFoo implementation, that won't be a problem (and it doesn't have to be virtual unless you want it overrideable).
This is an approach that works; whether it's overkill is a matter of taste, but I can see the merit in removing redundant code as part of refactoring, provided the classes are not public and/or not used outside your assembly. However instead of factoring code in this fashion I'd recommend using a tool such as ReSharper which will warn you about unused methods.

Can a method be abstract but not virtual?

As I understand it, a method being marked abstract is implicitly virtual. The reason: Suppose the compile-time type of a given object is abstract. If one of the object's abstract methods is being called, the actual method to be executed is the one defined in the object's runtime type. Isn't it? If I'm right then the abstract method behaves as if it is also virtual.
In spite of that, I have successfully marked a C# method both abstract and virtual simultaneously:
public abstract virtual void crazy();
I suppose it means that an abstract method is not necessarily virtual and being abstract is actually orthogonal to being virtual.
What do I get wrong? How can an abstract method not be virtual?
You cannot mark a method as both abstract and virtual. It will result in a compiler error:
The abstract method 'Namespace.Class.Foo()' cannot be marked virtual
The rest of your question is correct: abstract methods are implicitly virtual.
From MSDN
An abstract method is implicitly a virtual method.
Abstract method declarations are only permitted in abstract classes.
Because an abstract method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no braces ({ }) following the signature.
The implementation is provided by an overriding method, which is a member of a non-abstract class.
It is an error to use the static or virtual modifiers in an abstract method declaration.
"You cannot use the virtual modifier with the static, abstract, private, or override modifiers."
http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.100).aspx

How to define a must inherit class

How to define a must inherit class? in C#
You mark the class as abstract (this is the C# analogue to the VB.NET Must Inherit).
This will ensure it can't be instantiated directly.
From the linked MSDN article:
The abstract modifier indicates that the thing being modified has a missing or incomplete implementation. The abstract modifier can be used with classes, methods, properties, indexers, and events. Use the abstract modifier in a class declaration to indicate that a class is intended only to be a base class of other classes. Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class.
(emphasis mine)
Use the abstract modifier.
public abstract class MyClass()
{
...
}
You can define a class as abstract, or give it a protected-only constructor. abstract is better.
If u want to create a class, that has to be inherited, you'll need to mark it with the abstract modifier.
public abstract MyClass
{
}
It's not possible enforse needness of derivation or implementation in code, if that was a question.
But:
You can define an interface to force consumer to implement it.
Or you can define abstract class with only abstract members to force consumer to override all of them.
Hope this helps.
An interface would be best.
If you need to simulate the functionality , and its not a requirement that it fail at compile time...
define a method in the base class. Throw a an exception as the only line in the implementation. You might want to make the message very very clear about what the problem is.
override the method in the super class(es) and implement them.
If you fail to implement in a super class, you will get the exception.
Not perfect, but say you are trying to port code from vb.net... this could work.

How to prevent an abstract class with public derived classes from being inherited in other assemblies?

I want to write something like the following:
internal class InternalData
{
}
public class PublicData
{
}
abstract internal class Base {
internal Base() { }
private static InternalData CreateInternalDataFromPublicData(PublicData publicData)
{
throw new NotImplementedException();
}
abstract protected void DoProcess(InternalData internalData);
public void Process(PublicData publicData)
{
InternalData internalData = CreateInternalDataFromPublicData(publicData);
DoProcess(internalData);
}
}
public sealed class Derived : Base
{
protected override void DoProcess(InternalData internalData)
{
throw new NotImplementedException();
}
}
That is, Base contains some internal logic and is not intended to be inherited by classes outside of my assembly; and Derived is accessible from the outside.
InternalData also contains some internal logic and, as it would (and should) never be used from the outside, i also want to make it internal.
Of course the code above won't compile as the Base should not be less accessible than Derived. I can set the Base to be public, that's fine, but it leads to another problem.
If Base is public, then there could possibly be some ExternalDerived : Base in some other assembly. But Base.DoProcess accepts an InternalData as its argument, so that ExternalDerived cannot implement it (as it doesn't know about the InternalData).
Internal parameterless Base constructor prevents creation of any ExternalDerived instances, and thus nobody will implement ExternalDerived.DoProcess and no InternalData public exposure is needed, but the compiler doesn't know it.
How can i rewrite the code above so that there will be an abstract DoProcess(InternalData) method and so that InternalData class will be internal?
Since C# 7.2 there is private protected access modifier, which means "available only to derived classes in the same assembly".
In other words, it must meet conditions for both internal AND protected, unlike protected internal which applies to internal OR protected.
You can mark the base class' constructor as private protected, effectively preventing inheritance of that class through this constructor outside the assembly while still allowing inheritance within that assembly (and the assembly's friends).
So, a class like this:
public abstract BaseClass
{
private protected BaseClass() {}
}
is effectively sealed outside the assembly, while still inheritable within the assembly.
To make InternalData internal, DoProcess must be private or internal
(or InternalAndProtected, but C# doesn't support this CLR feature). It can't be protected or protected internal.
internal abstract DoProcess(InternalData internalData);
I'd probably also add an internal abstract void DoNotInheritFromThisClassInAnOutsideAssembly() member. That prevents anybody outside the assembly from inheriting from your class, because they can't implement that member and they get a reasonable compiler error. But you can't make the Base class itself internal.
I'd consider refactoring the code, so that you have no common base class. Probably by using some internal interfaces and composition.
It smells like you should use composition instead of inheritance. sorry, this is a very vague answer. I'm thinking more about this now..
The base type must be accessible, because otherwise, it becomes impossible to figure out its base. Your Base derives directly from System.Object, but how does a user of Derived know that? How does it know that Base doesn't derive from another public type, and that type's members should be made available?
If you mark everything in Base internal, except for the class itself, you've already prevented other assemblies from doing anything useful with it. In other words, if you make DoProcess internal, you can then prevent InternalData from becoming public.
Yes, admittedly this allows for bugs in your own assembly, if other classes try to call DoProcess. Unfortunately, there is no "accessible from derived classes in the same assembly" access modifier, only "accessible from derived classes", "accessible from the same assembly" and "accessible from derived classes and accessible from the same assembly". (Actually, .NET does support it, but C# doesn't.)
Set Base to be public.
public abstract class Base {...
Change Base.DoProcess:
protected virtual void DoProcess<T>(T internalData)
{
if (!(internalData is InternalData))
{
throw new ArgumentOutOfRangeException("internalData");
}
}
Change Derived.DoProcess:
protected override void DoProcess<T>(T internalData)
{
base.DoProcess(internalData);
// Other operations
}
It is actually quite straight forward. You just require that a deriving class implement an abstract internal method. Classes outside the library won't be able to implement the abstract method, and thus fail at compile time.
Your example, minimized to just the essentials:
abstract internal class Base {
internal protected abstract void DoProcess();
public void Process() {
DoProcess();
}
}
public sealed class Derived : Base {
internal protected override void DoProcess() {
throw new NotImplementedException();
}
}

Inheritance: only fields and methods?

Reading a book it says that the derived class inherits all fields and methods...but what about properties??
There seems to be a considerable amount of misinformation in the answers here. For the correct answer, see section 3.4 of the C# specification, which I reproduce for you here:
Members of a type are either declared in the type declaration or inherited from the base class of the type. When a type inherits from a base class, all members of the base class, except instance constructors, destructors and static constructors, become members of the derived type. The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that isn’t an instance constructor, static constructor, or destructor. However, an inherited member may not be accessible in a derived type, either because of its declared accessibility or because it is hidden by a declaration in the type itself.
I have added some emphasis to the relevant part. The key is that all members are inherited except for constructors and destructors. Members are inherited regardless of whether they are methods, fields, properties, events or indexers. Members are inherited regardless of whether they are public, private or protected. Members are inherited regardless of whether they are static, instance, virtual or abstract. All members are inherited.
A derived class inherits all methods fields and, yes, properties too, although private methods, fields and properties are generally not directly accessible or visible from the derived class unless it is nested in it's superclass (the parent). Constructors and finalizers, however, are not inherited so when you derive a type you always need to code any constructors that are required for your object initialization, even if it just calls down to the base class's constructor.
However, it is generally considered good practice to make your fields private and allow access to them, if necessary, to derived classes via properties. That way it allows you, the author of the base class, to have confidence that you control the way in which the classes state (the value of it's fields) can change.
To illustrate you question about properties:
public class Person
{
public Name { get; set; }
public void Greet()
{
Console.WriteLine("Hello");
}
}
public class Child : Person
{
public Nickname { get; set;}
}
In the above example, the derived class, Child, has a nickname (a property) in addition to its derived property (Name) and its derived method (Greet).
A property is syntactic sugar for a Get_ and Set_ method.
In other words: the compiler translates a property to one or two methods. So, they're inherited as well. :)
In a word, yes, properties are inherited along with the fields and the methods. Both private and public methods, fields and properties are inherited, but private members are inaccessible by the child class (unless the child class is nested within the base class - scoping and inheritance are connected but different things).
Properties, as implemented in C# (and most other languages that support them) are just a code-level abstract for a pair of methods that get and set the property, so having a int property called Age, is syntactic sugar for a couple of methods that are called int GetAge() and SetAge(int value), so it's natural that any rules that apply to methods applies evently to properties too.

Categories

Resources