Whilst learning some of the newer language features in C# I noticed that you can add abstract and virtual to non-static method definitions on interfaces, but I’m struggling to understand the purpose.
Here’s an example:
public interface IFoo
{
// Is there any functional difference between these two?
abstract string AbstractInstanceMethod();
string InstanceMethod();
// Or these two?
virtual string VirtualInstanceMethod() => "bar";
string InstanceMethodWithDefaultImplementation() => "bar";
}
I can see that with the virtual keyword you MUST provide an implementation and with the abstract keyword you MUST NOT provide an implementation. But these limitations only seem to the definition on the current interface, so I may as well CHOOSE to provide an implementation or CHOOSE NOT to provide an implementation.
In a derived interface you can override any of the above using the new keyword, then freely choose from abstract, virtual, or default implementations regardless of the original definition.
I’ve also tried to tease out any differences by creating derived classes with varying degrees of overrides/implementations, then invoking them to see which method bodies are executed, but it always just matches the type used in the variable definition.
It seems like the keywords just allow you to be more explicit, but I can’t find any documentation that confirms this. Can anyone help with this?
If the keywords are redundant, does anyone know of any Roslyn rules to disallow them? I like to avoid having two ways to write the same thing.
PS – Apologies if this is a dupe or just a bit of documentation that I’ve missed. I found it difficult to search due to the overloaded meanings of all the keywords.
>Solution :
It seems like the keywords just allow you to be more explicit, but I can’t find any documentation that confirms this. Can anyone help with this?
That is correct, and you can easily check the generated IL on your code to see that it has identical attributes:
.method public hidebysig newslot abstract virtual
instance string AbstractInstanceMethod () cil managed
{
} // end of method IFoo::AbstractInstanceMethod
.method public hidebysig newslot abstract virtual
instance string InstanceMethod () cil managed
{
} // end of method IFoo::InstanceMethod
.method public hidebysig newslot virtual
instance string VirtualInstanceMethod () cil managed
{
// Method begins at RVA 0x2050
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "bar"
IL_0005: ret
} // end of method IFoo::VirtualInstanceMethod
.method public hidebysig newslot virtual
instance string InstanceMethodWithDefaultImplementation () cil managed
{
// Method begins at RVA 0x2050
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "bar"
IL_0005: ret
} // end of method IFoo::InstanceMethodWithDefaultImplementation
If the keywords are redundant, does anyone know of any Roslyn rules to disallow them? I like to avoid having two ways to write the same thing.
No rules, but you can easily write your own analyzer if you’re so inclined. I will point out that there’s plenty of implicit keyword modifiers in C#, like private on fields, or internal on classes — this is nothing new.