using public, protected internal, protected, internal, private protected in interfaces C#10 - c#

I know that beginning from C#8, access modifiers were added for interfaces since before that all the members were implicitly public.
Then it appears that beginning with C#8 they did not let implicit implementations of members in implememting classes as described here or here but Clearly as of now implicit implementations are allowed since the following code compiles
public interface CS8 {
public void jj();
protected internal void jj1();
protected void jj2();
internal void jj3();
private protected void jj4();
}
public class ThisOne : CS8 {
public void jj() {
Console.WriteLine("8888");
}
public void jj1() {
Console.WriteLine("7777");
}
public void jj2() {
Console.WriteLine("6666");
}
public void jj3() {
Console.WriteLine("5555");
}
public void jj4() {
Console.WriteLine("4444");
}
}
I have been scouring the internet but can not find a clear answer
Why access modifiers were added for interfaces if the logic behind them has always been that they have to be public?
Why did they also add ability to implement the members inside the interface itself?
If you could show it to me maybe on an example for each modifier that would be great.
I can only imagine it is so you can control from where what implemented methods are accessible eben though all of the members regardless of the access modifier have to be implemented.
P.S
I apologize this is 2 questions.

Default implementations were added so interfaces could be updated without breaking the code of implementing classes so clients that use the interface as public APIs would not need to update their classes and add new methods properties etc. yet still get the new functionality.
private modifier became allowed so you could use them when working with default implementations.
protected was added to provide ability to extend the already defined default implementation.

Related

private members in interface

is this possible to create a private members in interface in .NET? I heard that it is possible now but I my IDE is rejecting it:
public interface IAnimal
{
void SetDefaultName(string name)
{
ChangeName(name);
}
private string defaultName = "NoName";
private void ChangeName(string name)
{
defaultName = name;
}
void Breath()
{
Console.WriteLine($"Default - I'm {defaultName}. <Breathing sounds>");
}
void Sound();
}
Yes! Now you can in C# 8.0 but it has to be a static member. Like this:
public interface IAnimal
{
static void SetDefaultName(string name)
{
ChangeName(name);
}
private static string defaultName = "NoName";
private static void ChangeName(string name)
{
defaultName = name;
}
void Breath()
{
Console.WriteLine($"Default - I'm {defaultName}. <Breathing sounds>");
}
void Sound();
}
But you need to keep in mind that static fields will be shared across the application. Changing the defaultName will result in changing it in every place where you are using IAnimal
private methods used to be prohibited in interfaces because interfaces are supposed to be contracts. They are a guarantee that "this class has the following methods and properties". Why would it be useful to guarantee that a class has a private method? It isn't useful, because no one else can call it!
In C# 8, this changed. You can now specify private interface default methods. Note that it has to be a default method, not the ones that doesn't have an implementation. Here's the docs stating that fact:
The syntax for an interface is relaxed to permit modifiers on its members. The following are permitted: private, protected, internal, public, virtual, abstract, sealed, static, extern, and partial.
...
It is an error for a private or sealed function member of an interface to have no body.
Here is a quote from the docs explaining why this is allowed:
Static and private methods permit useful refactoring and organization of code used to implement the interface's public API.
The actual question should be : should i do (or be able to do) it or not ?
The whole idea of the interface thing is to provide abstraction .
private members usually are implementation details that the consumer of your code shouldn't care about or know they exists so they don't belong to your abstract layer (interface)
the interface is the facade that the consumer will interact with ur service/component thorough , it should contain only the methods that the consumer will call , this is why originally interfaces should have only public modifiers
not to mention that putting such members in the interface will force every implementation of it to implement these members even if they don't need it
from my opinion the only reason C# changed interfaces and made them allow implementation is to make up for the language lack of support for multiple class inheritance , but that does mean that you should miss use ur interfaces like that
Yes, with C# 8.0, you can have public, private and protected members.
For example, following works:
public interface ITest
{
private SomeEnum EnumTy { get => SomeEnum.Value1; }
}
If a class implements an interface and tries to access the variable, they will get an error.
public class TestImpl : ITest
{
ITest.EnumTy = SomeEnum.Value2; // gives an error
}
The members can also be protected. As a suggestion, going forward its good to have public before methods to indicate more readability (even though public is default).
A good article is here:
https://jeremybytes.blogspot.com/2019/11/c-8-interfaces-public-private-and.html

Order of execution in Abstract Class

I came across a posting where it is said that MustBeCalled() method will get called if we have the Abstract class do the calling in this manner.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
//could also be public if desired
protected abstract void AbstractMethod();
}
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
But how does MustBeCalled() method get called?
In what order things are called here?
If you call PerformFunction() first, then everything will execute in the intended order, where that order is specified in the order of the lines of code in PerformFunction(). If you call AbstractMethod() directly, there's no guarantee that MustBeCalled() will ever be called. However, I notice that you have AbstractMethod() marked as protected, which means that outside consumers of your class will not be able to call it directly. They'll have to use PerformFunction() -- this is good, as there is now only one public way to invoke your internal methods, and that way guarantees the order that you need.
In truth, there is a level at which you can only guarantee that things happen by choosing to write code to make them happen. You can't, for example, guarantee that code is going to implement a game of Tetris except by actually writing that code and choosing to implement it in such a way that it produces Tetris behavior. The type system and the public/protected/private modifiers can help some by preventing some misuse (as your internals are not accessible and thus cannot be invoked by consumers of your module), but they can only go so far. This is such a case.
You cannot enforce how an implementation to call a method when invoked. The implementation could do its own thing entirely, or do nothing.
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
// this is a perfectly valid implementation
}
}
A better implementation could be.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
private void MustBeCalled()
{
}
protected virtual void AbstractMethod()
{
MustBeCalled();
}
}
This way refactoring tools will at least create the desired boilerplate code:
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
base.AbstractMethod();
}
}
However, the person overriding AbstractMethod still needs to call base.AbstractMethod, this is not enforced by the compiler at all.

C# internal interface with internal implementation

I've struck upon something I don't really understand.
I have a project, where I have an interface that is internal. The class that implements that interface is also internal. In the implementation of the interface, I make all the members that I implement, internal. I did not do an explicit implementation.
I have two interfaces and two classes that implement those interfaces where this works fine.
It would look something like this:
internal interface IA
{
void X();
}
and then
internal class CA : IA
{
internal void X()
{
...
}
}
This works fine for the two aforementioned classes. But when I try to do it with another interface and class, it doesn't work. In fact, for the example above, I get the error:
'WindowsFormsApplication1.CA' does not implement interface member 'WindowsFormsApplication1.IA.X()'. 'WindowsFormsApplication1.CA.X()' cannot implement an interface member because it is not public.
I realize I can make the methods public or do an explicit implementation (and omit the internal and public modifiers), but I'm simply confused as to why it works with the two classes it works with and yet I seem to be unable to replicate it anywhere else.
Butchering the code a bit (because it's confidential), this is one of the ones that actually works in my project.
internal interface IScanner
{
void SetHardware(Hardware hardware);
void Start();
void PauseScan();
void ResumeScan();
void Stop();
bool InScan { get; }
event ScanCompleteHandler ScanComplete;
}
Then I have the class:
internal class MyScanner : IScanner
{
internal void SetHardware(Hardware hardware)
{
...
}
internal void Start()
{
...
}
internal void Stop()
{
...
}
internal void PauseScan()
{
...
}
internal void ResumeScan()
{
...
}
internal bool InScan
{
get
{
...
}
}
internal event ScanCompleteHandler ScanComplete;
}
To make things even stranger, I created another internal class called Temp. I then had it implement the IScanner interface and I copied and pasted the implementation from MyScanner over to it and it won't compile, giving me the error that: "cannot implement an interface member because it is not public."
Can anyone explain this inconsistency?
Thanks
(Updated to fix a typo and clarify some text)
EDIT: Additional Information
I ran the code through reflector and my implementations have been compiled as explicit implementations, even though they aren't explicit. Reflector shows no signs of the internal keywords. All I can guess is that this is some sort of glitch in the compiler that, for some reason, allowed me to make them internal and implicit and that it somehow resolved that as being an explicit implementation.
I've looked over the code a number of times. I can't find any other explanation for it.
If you are implicitly implementing an interface I believe that the member must be declared public. In your example, CA attempts to implicitly implement the X() method but isn't declared public. If you want to keep X() as internal then you should use explicit interface implementation.
void IA.X() { /* stuff */ }
However, I'll also add that making the X() method public wouldn't do any harm anyway as the class is internal so that member is already restricted by that access modifier... That is, it's already effectively internal... So you might as well just make it public!
I know it has been a while since this question was asked, but maybe I can shed some light on it. According to the C# language specification found here the behavior you described should not be possible. Because under 20.4.2 Interface mapping it is said that the implementation is either explicit or mapped to a public non-static member. So either you have some other scenario than the one you are describing here, or you found a bug in your compiler :).
Probably that your "Temp" class is public and IScanner is internal. This is the reason why you get this error. I consider this very annoying since your are forced to implement it explicitly you cannot specify them as abstract or virtual. For the virtual stuff, I was forced to do an implicit internal virtual implementation of the same API and then call the implicit version from the explicit one. Ugly.
If your intention is to hide a certain implementation from outside, you can implement it explicitly like this:
internal class LDialogService : ILDialogService, ILDialogInternalService
{
public async Task<TValue> ShowAsync<TValue>(ILDialogFragment fragment)
{
throw new NotImplementedException();
}
void ILDialogInternalService.SetComponent(LDialog component)
{
throw new NotImplementedException();
}
}
In the above code, I want to expose ShowAsync method to the outside but keep SetComponent inside. Since ILDialogInternalService is internal, no one can call it from outside except through Reflection.
To all my knowledge you cannot implement interface methods internal. As you stated you can implement them explicitly but then someone can still do ((IScanner)myScanner).SetHardware(hw)
Are you 100% sure your MyScanner implementation does not do something like this:
internal class MyScanner : IScanner
{
void IScanner.SetHardware(Hardware hardware) { this.SetHardware(hardware); }
internal void SetHardware(Hardware hardware)
{
...
}
....
}
or this:
internal partial class MyScanner : IScanner
{
internal void SetHardware(Hardware hardware)
{
...
}
}
internal partial class MyScanner
{
void IScanner.SetHardware(Hardware hardware)
{
this.SetHardware(hardware);
}
}
It's OK to have an internal modifier in an Interface declaration however you CAN'T have ANY modifiers INSIDE the interface, in other words, you can't have any modifier for the interface Members. It's simple as that!
Example:
internal interface IA
{
void X(); //OK. It will work
}
internal class CA : IA
{
**internal** void X() // internal modifier is NOT allowed on any Interface members. It doesn't compile. If it works in your project it's because either you DON'T have the void X() method in the Interface or your are inheriting from a wrong interface maybe accidentally
{
...
}
}
An interface declaration may declare zero or more members. The members of an interface must be methods, properties, events, or indexers. An interface cannot contain constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind.
All interface members implicitly have public access. It is a compile-time error for interface member declarations to include any modifiers. In particular, interfaces members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static.
Reference:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/interfaces

C# - Class design & access modifiers

Given the following:
public abstract class Base
{
// other stuff
public static void StaticMethod()
{
PrivateMethod();
}
// here should be PrivateMethod() declaration somehow
}
public sealed class Derived: Base
{
// other stuff
public void InstanceMethod()
{
// call somehow PrivateMethod
PrivateMethod();
}
}
I need to make use of PrivateMethod() from 2 different contexts (different assemblies). Once calling Base.StaticMethod(), and the second time by using an instance of the Derived class d.InstanceMethod();.
I am looking for a way how to design PrivateMethod() inside the Base class. Of course PrivateMethod() should not be visible outside the Base and Derived classes.
I was thinking something about "protected static PrivateMethod() {}" but I read I should not do that...
What do you recommend guys?
protected static void PrivateMethod() {}
Is OK (apart form the name) and does what you require. You won't need base. when calling it from Derived.
I had never heard this before, so I went looking for something that said what you described. I found this article: New Design Guideline: Avoid Protected Static. However, it only talks about protected static field.
I don't think the article actually makes a good case for what it is trying to say. Rather than just describing how protected statics can lead to complications, it uses a very simple example of the base class designer not setting the right access flags for something that should not be accessed by everyone.
That being said, there is still a point that protected static can lead to complications. Protected static means that any subclass can call a method at any time. This can lead to thread safety concerns if the method is written naively. It seems like the article was written in a way that it conveys "Don't do it" rather than "If you need to do it, be careful."
You could just call the public StaticMethod() from your derived class's InstanceMethod() ... since it indirects back to PrivateMethod() anyway. That way you can leave PrivateMethod() private. The implementation would be something like:
public abstract class Base
{
// other stuff
public static void StaticMethod()
{
PrivateMethod();
}
// here should be PrivateMethod() declaration somehow
private static void PrivateMethod()
{
// do stuff
}
}
public sealed class Derived: Base
{
// other stuff
public void InstanceMethod()
{
// call somehow PrivateMethod
StaticMethod();
}
}
PS: If there is need during StaticMethod to differentiate between a public caller or a derived class caller (from InstanceMethod) it could be either passed as parameter, or determined via reflection.

Why does FxCop treat protected as public?

Why does FxCop treat protected members as if they are public throwing DoNotDeclareVisibleInstanceFields error? I'm pretty sure protected members is a valid code design.
It's telling you not to declare fields which are visible outside the class, i.e. not private. In this case it is correctly recognising the protected modifier as exposing the members outside the class, albeit only to derived types.
I'm not sure if that's what you meant, but in general protected members are part of a class' interface.
You don't want public member variables because they make your implementation inflexible. Protected member variables do the same since classes that inherit from yours will depend on them, thus making your implementation inflexible.
Asaf
It looks like the error you're getting is flagging your externally visible instance fields. The recommended practice here is to make this field private and expose it through an externally visible property (with a public or protected access modifier).
The MSDN page on the error gives a good example:
using System;
namespace DesignLibrary
{
public class BadPublicInstanceFields
{
// Violates rule DoNotDeclareVisibleInstanceFields.
public int instanceData = 32;
}
public class GoodPublicInstanceFields
{
private int instanceData = 32;
public int InstanceData
{
get { return instanceData; }
set { instanceData = value ; }
}
}
}

Categories

Resources