Why must methods implementing internal interfaces be public - c#

I am developing an internal class that implements an internal interface.
Can anyone explain why I cannot declare my method as internal, why I am getting the following error: "cannot implement an interface member because it is not public".
I know that I have to declare the method as public, but it makes absolutely no sense to me.
What is the point of declaring a method public if both the interface and the class are internal?
Is it not misleading?
I have read a related question on this site. It is not an exact duplicate, because my class is internal.

Simply put: because that's the way the language designers designed it. Even in internal interfaces, the methods are implicitly public. It does make things simple, but it's a pain in other ways.
If you want a public class where you want to "hide" the use of an internal interface, you could use explicit interface implementation - although that has other drawbacks.
Of course, if your class is internal then it doesn't matter that the methods are public anyway - other assemblies aren't going to be able to call the methods because they can't see the type.
I definitely agree that C# (or .NET in general) hasn't been designed as carefully as it might be around internal interfaces.
In terms of exactly why you're getting an error message - section 13.4.4 of the C# 4 spec (interface mapping) is the reason. Implementations are only found for nonstatic public members and explicit interface member implementations - and if there are any unimplemented members in the interface, an error occurs.

I know this is old but maybe someone find it useful. You can accomplish a kind of internal interface methods like this:
internal interface IFoo
{
void MyMethod();
}
public abstract class Foo : IFoo
{
void IFoo.MyMethod()
{
MyMethod();
}
internal abstract void MyMethod();
}
So all your internal classes should derive from Foo and are forced to implement the abstract MyMethod. But you can treat them all as IFoo of course. But those classes outside the assembly won't provide the MyMethod class.
So you have the advantage to treat your classes internally as IFoo and rely on MyMethod. The drawback is that all your classes will need to derive from Foo which can be a problem if you need another base class.
But I found it helpful if the abstract base class is a generic one and the interface is not. Maybe it is useful in some cases.

Related

Why cannot implicitly implement a non-public interface member?

Interface:
interface IMyInterface{
internal int Property {get; set;}
}
Class:
public class MyClass: IMyInterface{
internal int Property {get; set;}
}
Result:
CS8704 Error: MyClass doesnot implement interface member Property.get MyClass cannot implicitly implement a non-public member.
Why I have to implement the interface explicitly?
The simple answer to "why is a language like this" is "because that's how the language designers specified it".
Now, why did they design it that way? Some of the official notes I found were these. It seems the main question was about what kind of access the implementor must have:
Would we allow non-public interface members to be implemented implicitly? If so, what is required of the accessibility of the implementing method? Some options:
Must be public
Must be the exact same accessibility
Must be at least as accessible
They decided:
For now, let's simply not allow it. Only public interface members can be implicitly implemented (and only by public members).
The "for now" never changed, so as of C# 8 an interface can have non-public virtual members but a class may only implement them explicitly.
I can speculate on a couple of reasons they may have decided against implicit overrides like this:
Non-public virtual methods in interfaces may have been considered a "rare" feature (after all, aren't interfaces supposed to document the public behavior of a class?), not worth putting a lot of resources into in terms of the semantics of implicit overrides.
Unlike with method overridding in class-to-class inheritance, an class method implementing an interface method doesn't use the override keyword. It might have been considered confusing to see a protected and/or internal method and not realize that it's fulfilling an interface contract. (Public methods are presumably considered exempt from this concern because that's the way they've always worked, and public methods are part of the class' public contract anyway so modifying / removing them would already be cause the reader to think about other parts of code that depend on it.)
Interfaces can only override other interface methods explicitly, possibly again because allowing interface-to-interface implicit implementation would be too expensive for the compiler and tooling teams and too confusing for C# users. (Especially since interface-to-interface inheritance is multiple-inheritance.) Since both this and non-public interface methods were introduced in general in C# 8, it may have made sense to make the two features match syntactically.
See also the notes on this question in the default interface method proposal.
Interface members don't have scopes like public or internal. What you have here is a default interface implementation.
So you need to remove the scope on the interface:
interface IMyInterface{
int Property {get; set;}
}
The internal property forces the implementation to be explicit such that the internal members of the interfaces will remain internal to the assembly.
It helps you to keep implementations internal (to an assembly) so that you can update code without breaking changes e.g. renaming the property.
interface IMyInterface
{
internal int Property { get; set; }
}
public class MyClass : IMyInterface
{
int IMyInterface.Property { get; set; }
}

Why its possible to override explicit implementation?

We usually implement interfaces explicitly when it’s not right to access interface member directly from implementer class. Weather it has to be internal or it causes conflicts with API design or when it increases the chance of misusing methods.
Implementing members individually for multiple interfaces with different logic is absolutely discouraged in my mind so that’s not case here
Compiler does not allow making such implementation as virtual because it doesn't make sense and I think it’s right. Usually explicit implementation is very sensitive and that’s why you try to hide it.
However I found following way of over-riding explicit implementation (it’s not exactly override but its cheating alternative)
I found this surprising and quite disappointing. My question is why following code is allowed and works perfectly? I expected to get error that interface is already implemented explicitly.
This is just basic example to reproduce problem
static void Main(string[] args)
{
var b = new Base();
((IInterface)b).Write();
var c = new Child();
((IInterface)c).Write();
}
public interface IInterface
{
void Write();
}
public class Base : IInterface
{
void IInterface.Write()
{
Console.WriteLine("Base");
}
}
public class Child : Base, IInterface // hack is here. Re Implemented :/
{
void IInterface.Write()
{
Console.WriteLine("Child");
}
}
Outputs
Base
Child
why following code is allowed and works perfectly?
Because the specs say so:
It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a
compile-time error to include the modifiers abstract, virtual, override, or static.
Yet in polymorphism, the saying goes "the more derived type knows better", from the specs again:
derived classes can extend and specialize base classes
So the most derived type who implements that interface explicitly will be called when you invoke that interface member.
I suggest you to think at the low level translation from C# into native code: the interface inheritance redeclaration, and the one or more of its methods overriding, forces rewriting of the VMT - Virtual Method Table (interface methods are virtual by design).

Abstract Method in Non Abstract Class

I want to know the reason behind the design of restricting Abstract Methods in Non Abstract Class (in C#).
I understand that the class instance won't have the definition and thus they wont be callable, but when static methods are defined,they are excluded from the instance too. Why abstract methods are not handled that way, any specific reason for the same?
They could be allowed in concrete class and the deriving class can be forced to implement methods, basically that is what, is done in case of abstract methods in an abstract class.
First, I think that what you're asking doesn't logically make sense. If you have an abstract method, it basically means that the method is unfinished (as #ChrisSinclair pointed out). But that also means the whole class is unfinished, so it also has to be abstract.
Or another way to put it: if you had an abstract method on a class that wasn't abstract, that would mean you had a method that cannot be called. But that means the method is not useful, you could remove it and it would all work the same.
Now, I'll try to be more concrete by using an example: imagine the following code:
Animal[] zoo = new Animal[] { new Monkey(), new Fish(), new Animal() };
foreach (Animal animal in zoo)
animal.MakeSound();
Here, Animal is the non-abstract base class (which is why I can put it directly into the array), Monkey and Fish are derived from Animal and MakeSound() is the abstract method. What should this code do? You didn't state that clearly, but I can imagine few options:
You can't call MakeSound() on a variable typed as Animal, you can call it only using a variable typed as one of the derived classes, so this is a compile error.
This is not a good solution, because the whole point of abstract is to be able to treat instances of derived classes as the base class, and still get behaviour that's specific to the derived class. If you want this, just put a normal (no abstract, virtual or override) method into each derived class and don't do anything with the base class.
You can't call MakeSound() on an object whose runtime type is actually Animal, so this is a runtime error (an exception).
This is also not a good solution. C# is a statically typed language and so it tries to catch errors like “you can't call this method” at compile time (with obvious exceptions like reflection and dynamic), so making this into a runtime error wouldn't fit with the rest of the language. Besides, you can do this easily by creating a virtual method in the base class that throws an exception.
To sum up, you want something that doesn't make much sense, and smells of bad design (a base class that behaves differently than its derived classes) and can be worked around quite easily. These are all signs of a feature that should not be implemented.
So, you want to allow
class C { abstract void M(); }
to compile. Suppose it did. What do you then want to happen when someone does
new C().M();
? You want an execution-time error? Well, in general C# prefers compile-time errors to execution-time errors. If you don't like that philosophy, there are other languages available...
I think you've answered your own question, an abstract method isn't defined initially. Therefore the class cannot be instanciated. You're saying it should ignore it, but by definition when adding an abstract method you're saying "every class created from this must implement this {abstract method}" hence the class where you define the abstract class must also be abstract because the abstract method is still undefined at that point.
The abstract class may contain abstract member. There is the only method declaration if any method has an abstract keyword we can't implement in the same class. So the abstract class is incompleted. That is why the object is not created for an abstract class.
Non-abstract class can't contain abstract member.
Example:
namespace InterviewPreparation
{
public abstract class baseclass
{
public abstract void method1(); //abstract method
public abstract void method2(); //abstract method
public void method3() { } //Non- abstract method----->It is necessary to implement here.
}
class childclass : baseclass
{
public override void method1() { }
public override void method2() { }
}
public class Program //Non Abstract Class
{
public static void Main()
{
baseclass b = new childclass(); //create instance
b.method1();
b.method2();
b.method3();
}
}
}
You can achieve what you want using "virtual" methods but using virtual methods can lead to more runtime business logic errors as a developer is not "forced" to implement the logic in the child class.
I think there's a valid point here. An abstract method is the perfect solution as it would "enforce" the requirement of defining the method body in children.
I have come across many many situations where the parent class had to (or it would be more efficient to) implement some logic but "Only" children could implement rest of the logic"
So if the opportunity was there I would happily mix abstract methods with complete methods.
#AakashM, I appreciate C# prefers compile time errors. So do I. And so does anybody. This is about thinking out-of-the-box.
And supporting this will not affect that.
Let's think out of the box here, rather than saying "hurrah" to big boy decisions.
C# compiler can detect and deny someone of using an abstract class directly because it uses the "abstract" keyword.
C# also knows to force any child class to implement any abstract methods. How? because of the use of the "abstract" keyword.
This is pretty simple to understand to anyone who has studied the internals of a programming language.
So, why can't C# detect an "abstract" keyword next to a method in a normal class and handle it at the COMPILE TIME.
The reason is it takes "reworking" and the effort is not worth supporting the small demand.
Specially in an industry that lacks people who think out of the boxes that big boys have given them.
It's still not clear why you would want that, but an alternative approach could be to force derived classes to provide a delegate instance. Something like this
class MyConcreteClass
{
readonly Func<int, DateTime, string> methodImpl;
// constructor requires a delegate instance
public MyConcreteClass(Func<int, DateTime, string> methodImpl)
{
if (methodImpl == null)
throw new ArgumentNullException();
this.methodImpl = methodImpl;
}
...
}
(The signature string MethodImpl(int, DateTime) is just an example, of course.)
Otherwise, I can recommend the other answers to explain why your wish probably isn't something which would make the world better.
So the answers above are correct: having abstract methods makes the class inherently abstract. If you cannot instance part of a class, then you cannot instance the class itself. However, the answers above didn't really discuss your options here.
First, this is mainly an issue for public static methods. If the methods aren't intended to be public, then you could have protected non-abstract methods, which are allowed in an abstract class declaration. So, you could just move these static methods to a separate static class without much issue.
As an alternative, you could keep those methods in the class, but then instead of having abstract methods, declare an interface. Essentially, you have a multiple-inheritance problem as you want the derived class to inherit from two conceptually different objects: a non-abstract parent with public static members, and an abstract parent with abstract methods. Unlike some other frameworks, C# does permit multiple inheritance. Instead, C# offers a formal interface declaration that is intended to fill this purpose. Moreover, the whole point of abstract methods, really, is just to impose a certain conceptual interface.
I have a scenario very similar to what the OP is trying to achieve. In my case the method that I want to make abstract would be a protected method and would only be known to the base class. So the "new C().M();" does not apply because the method in question is not public. I want to be able to instantiate and call public methods on the base class (therefore it needs to be non-abstract), but I need these public methods to call a protected implementation of the protected method in the child class and have no default implementation in the parent. In a manner of speaking, I need to force descendants to override the method. I don't know what the child class is at compile time due to dependency injection.
My solution was to follow the rules and use a concrete base class and a virtual protected method. For the default implementation, though, I throw a NotImplementedException with the error "The implementation for method name must be provided in the implementation of the child class."
protected virtual void MyProtectedMethod()
{
throw new NotImplementedException("The implementation for MyProtectedMethod must be provided in the implementation of the child class.");
}
In this way a default implementation can never be used and implementers of descendant implementations will quickly see that they missed an important step.

interface with base class and derived class to achieve multiple inheritance

I got the following code where i would like to know the relationship between those class and interface.
Multiple inheritance wont work with C# but can we implement using interface?
Please tell me whether the following code will complie or not? why it is so ?
I am very confused?
Pleasehelp me out........
public interface MyInterface
{
void Method();
}
public class Base
{
public void Method() { }
}
public class Derived : Base, MyInterface { }
Please tell me whether the following code will complie or not?
Yes, it will - but you could have found that out for yourself just by trying it.
Why it is so?
Quite simply, Derived implements the contract required by MyInterface. It happens to do that via Base which is unaware of the interface, but it still has all the relevant members.
There's a danger here, though - in reality, interfaces are about more than just having appropriate members available for callers; they're about the semantics of those members. A class hierarchy like this only works when the semantics of Base.Method() exactly match the requirements of MyInterface.Method() by coincidence (as opposed to by explicit, declared design). Even if it's valid to start with, the maintainer of Base may decide to make a change to the behaviour of Method which is valid according to what Base.Method has guaranteed, but isn't valid according to what the interface guarantees.
EDIT: In terms of the language specification, this is in section 13.4.4 of the C# 4 spec:
A class or struct must provide implementations of all members of the interfaces that are listed in the base class list of the class or struct. The process of locating implementations of interface members in an implementing class or struct is known as interface mapping.
Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located.
[...]
A compile-time error occurs if implementations cannot be located for all members of all interfaces specified in the base class list of C.

C#: Abstract classes need to implement interfaces?

My test code in C#:
namespace DSnA
{
public abstract class Test : IComparable
{
}
}
Results in the following compiler error:
error CS0535: 'DSnA.Test' does not implement interface member
'System.IComparable.CompareTo(object)'
Since the class Test is an abstract class, why does the compiler require it to implement the interface? Shouldn't this requirement only be compulsory for concrete classes?
In C#, a class that implements an interface is required to define all members of that interface. In the case of an abstract class, you simply define those members with the abstract keyword:
interface IFoo
{
void Bar();
}
abstract class Foo : IFoo
{
public abstract void Bar();
}
Or to put it another way: you don't have to "implement" it (which would be a terrible limitation on abstract classes); however, in C#, you do have to tell the compiler that you are deliberately passing the buck to concrete subclasses - and the above line of code shows how to do so.
The comments and downvotes complaining that this is not an answer to the question are missing the point. Someone coming to Stack Overflow, having received this compiler error, but having an abstract class in which it would be a mistake to supply an implementation, are stuck without a good solution - would have to write implementation methods that threw runtime exceptions, a horrendous work-around - until they have the above information. Whether it is good or bad that C# requires this explicitness is outside the scope of Stack Overflow, and not relevant to the question nor this answer.
Unlike Java, in C#:
"an abstract class must provide implementations of all members of the interfaces that are listed in the base class list of the class. However, an abstract class is permitted to map interface methods onto abstract methods."
https://msdn.microsoft.com/en-us/library/Aa664595(v=VS.71).aspx
They don't have to actually implement the interface.The interface methods/properties can be abstract or even virtual as well. So its up to the subclasses to actually implement them.

Categories