Strange limitation in the implementation of internal interface - c#

I have code
internal interface IFoo
{
void foo();
}
public class A : IFoo
{
// error CS0737: 'A' does not implement interface member 'IFoo.foo()'.
//'A.foo()' cannot implement an interface member because it is not public.
internal void foo()
{
Console.WriteLine("A");
}
}
Why such strange limitation? I have internal interface and why I can't create internal method in interface realization?

This is because interfaces can't specify anything about the visibility of members, only the members themselves. All members that implement an interface must be public. The same happens when you implement a private interface.
One solution might be explicitly implementing the interface:
internal interface IFoo
{
void foo();
}
public class A : IFoo
{
void IFoo.foo()
{
Console.WriteLine("A");
}
}
In the above code, you must have an instance of A cast to IFoo to be able to call foo(), but you can only do such a cast if you are internal compared to the class and hence have access to IFoo.

Related

If we cannot use access-protected modifiers within an interface what are the options?

As the title says: If we cannot use access-protected modifiers within an interface then what can we use in c#?
The only answer found is to use an abstract class?
Interface members are required to be public.
If you need members with access modifiers that you are required to implement in the child class, use abstract members in a parent class.
abstract class BaseClass
{
protected abstract SomeMethod();
}
class Child : BaseClass
{
// You will be required to implement SomeMethod() or declare abstract.
}
Interfaces don't allow member access modifiers but the interfaces themselves can have any access modifier valid for a regular class. This used jointly with explicitly implemented interfaces allows, in a way, member level access modifiers. Consider the following code:
internal interface IFoo
{
void Frob();
}
public interface IBar
{
void Blah();
}
public class Foo : IFoo, IBar
{
void IFoo.Frob() { }
public void Blah() { }
}
And you essentially have the moral equivalent of a hypothetical:
public interface IFooBar
{
public void Blah();
internal void Frob();
}
Although it is true that there is no way around the fact that Frob must be implemented explicitly, at least as c# stands today.

Abstract method in public abstract class implementing an internal interface doesn't compile?

internal interface I_Foo
{
void Bar();
}
public abstract class A_Foo : I_Foo
{
public A_Foo() { }
abstract void I_Foo.Bar();
}
public class Foo : A_Foo
{
public Foo() : base() { }
internal override void Bar()
{
}
}
Hello! I'm trying to have some methods visible to outside code, and other only visible to my assembly. For this purpose, I made an internal interface I_Foo to serve as a contract to other parts of the assembly, a public abstract A_Foo to serve as abstraction for external code, and centralize some constructor functionality, and several different classes Foo that implement A_Foo and I_Foo explicitly to retain internal modifier.
However, in the A_Foo class, I get
'A_Foo.I_Foo.Bar()' must declare a body because it is not marked abstract, extern, or partial
even though the method is clearly marked as "abstract". If I add a body, I get "abstract is not a valid modifier".
I need this method to be explicitly declared, in order to be internal in a public class, and I need it to be abstract so I can override it in the actual implementation Foo.
Why doesn't the compiler let me?
Is there another way I can achieve the same thing?
Thank you.
Explicit interface implementations always have to have an actual implementation. The trick here is to making that just call a non-explicit (internal) abstract method:
public abstract class A_Foo : I_Foo
{
// Classes outside the assembly can't derive from A_Foo
// anyway, so let's make the constructor internal...
internal A_Foo() { }
void I_Foo.Bar()
{
Bar(); // Just delegate to the abstract method
}
internal abstract void Bar();
}
This still allows I_Foo to use internal types etc, because Bar is never exposed publicly - but it fits within the other rules of the language.
The method can not be abstract. THe problem is that you try to use explicit interface implementation (void I_Foo.Bar). Those methods can not be overwritten later - so they have to be implemented.
If you declare Bar directly (void Bar()) then it can be abstract.

How to reference abstract method from an implemented class in C#

I have a base class (A), below, that I always want to inherited from
class A
{
abstract protected int foo();
public int foo2()
{
//do some stuff
foo();
}
}
This will not work because I can't have an abstract method in non-abstract class. But how can I accomplish the follow goals:
classes that inherit class A will have foo2 already implemented but classes that inherit MUST implement foo? It would also be preferable that foo2 is overridable.
Update: Class A did NOT have to be non-abstract
Just make the class A abstract. Abstract classes can have some methods implemented.
Make foo2() virtual, then classes derived from A can override it.
I expect that you have a valid reason to not make A abstract. The prefered way to change the behaviour of an existing non abstract class is to inject that behaviour.
interface IFoo
{
int Foo();
}
class A
{
private IFoo foo;
public A(IFoo foo)
{
this.foo = foo;
}
public int Foo2()
{
//...
return foo.Foo();
}
}
you will receive errors when you build the project
you can't define abstract method in non-abstract class
Exception
Error 1 ' .A.foo()' is abstract but it is contained in non-abstract class

C# best partial interface implementation in base/abstract class

.net does not allow partial interface implementation in base classes. As a mitigation I've come to 3 alternate solutions. Please help me decide which is more universal in terms of refactoring, compile/run time errors, readability.
But first a couple of comments.
Of course you may always cast object to IFoo and call any method without any compiler warning. But it's not logical, you wouldn't do that normally. This construct wouldn't occur as a result of refactoring.
I want maximum separation. Direct class contract (public methods and properties) should be separated with interface implementations. I use interfaces a lot to separate object interations.
My comparison:
BaseClass1/MyClass1:
con: Have to create virtual abstract in BaseClass1 for each not implemented method of IFoo.
con: Additional method wrap - slight productivity impact at runtime.
BaseClass2/MyClass2:
con: no compiler warning if no implementation of Method2 in MyClass2. Runtime exception instead. Refactoring with poor unit test coverage may potentially destabilize code.
con: has to put additional obsolete construct to prevent direct method call from child classes.
con: Method2 is public for BaseClass1 so it's part of class contract now. Have to put "Obsolete" construct to prevent direct call, not via IFoo.
BaseClass3/MyClass3:
pro: (Compared to #2). More readable. You see that MyClass2.Method2 is IFoo implementation, not just some overriden method.
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
IFooMethod2();
}
protected abstract void IFooMethod2();
}
public class MyClass1 : BaseClass1
{
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
protected override void IFooMethod2()
{
//some implementation
}
}
public abstract class BaseClass2 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
public virtual void Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass2 : BaseClass2
{
public override void Method2()
{
//some implementation
}
}
public abstract class BaseClass3 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass3 : BaseClass3, IFoo
{
void IFoo.Method2()
{
//some implementation
}
}
I like this version, the base class can't be instantiated because its abstract, the derived class must list IFoo in its declaration or else it won't be implementing the interface and then it is solely responsible for implementing the rest of the interface.
One drawback I can see is you can't explicitly implement the interface methods in the base class (ie no IFoo:Method1), but otherwise this is a fairly low overhead version.
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1
{
public void Method1()
{
//some implementation
}
}
public class MyClass1 : BaseClass1, IFoo
{
public void Method2()
{
//some implementation
}
}
Ok, you could try the following as BaseClass is abstract:
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass : IFoo
{
public void Method1()
{
// Common stuff for all BaseClassX classes
}
// Abstract method: it ensures IFoo is fully implemented
// by all classes that inherit from BaseClass, but doesn't provide
// any implementation right here.
public abstract void Method2();
}
public class MyClass1 : BaseClass
{
public override void Method2()
{
// Specific stuff for MyClass1
Console.WriteLine("Class1");
}
}
public class MyClass2 : BaseClass
{
public override void Method2()
{
// Specific stuff for MyClass2
Console.WriteLine("Class2");
}
}
private static void Main(string[] args)
{
IFoo test1 = new MyClass1();
IFoo test2 = new MyClass2();
test1.Method2();
test2.Method2();
Console.ReadKey();
}
It is extremely bad to design a class that doesn't implement a well-defined contract. It is extreme because you firstly say that a class is capable of doing something. You explicitly highlight that the class can do stuff, but later in the code you say nahh, screw it, this class can live without implementation. Compiler very wisely asks you to implement the contract, but it is left up to you to decide.
Here are some common solutions
Bad solution
Throw an exception (NonImplementedException or NotSupportedException, see sample)
Declare it as obsolete (design it good from the beginning)
Better solution
Explicit interface implementation, but you still implement it (just kind of hide it)
Best solution
Use interface segregation (split your fat interface into thinner and more manageable ones)
I'd suggest having the abstract base class implement the interface with methods that call protected abstract methods, as shown in your first example, except for methods which some derived classes may not implement (following the "throw everything into IList but don't have all the methods actually work" pattern); those could be protected virtual stubs which throw NotSupportedException.
Note that it is up to the child class whether to expose any particular member of the interface as a like-named public member (which could call the appropriate abstract member).
The proper pattern in VB.net would be something like MustOverride Sub IFoo_Method1() Implements IFoo.Method1, which would avoid the extra function call overhead, but C# doesn't provide any means of implementing an interface with a protected member. Using explicit interface implementation for any method which may have to be overridden in a child class is somewhat icky, because it's impossible for the child's re-implementation of the interface to chain to the parent's implementation.

C# inherited protected method implementing interface

I have this class/interface definitions in C#
public class FooBase {
...
protected bool Bar() { ... }
...
}
public interface IBar {
bool Bar();
}
Now I want to create a class Foo1 derived from FooBase implementing IBar:
public class Foo1 : FooBase, IBar {
}
Is there some class declaration magic that the compiler takes the inherited protected method as the publicly accessible implementation of the interface?
Of course, a Foo1 method
bool IBar.Bar()
{
return base.Bar();
}
works. I'm just curious whether there is a shortcut ;)
Omitting this method results in a compiler error: Foo1 does not implement interface member IBar.Bar(). FooBase.Bar() is either static, not public, or has wrong return type.
Explanation: I separate code inheritance (class hierarchy) and feature implementation (interfaces). Thus for classes implementing the same interface, accessing shared (inherited) code is very convenient.
No shortcut. In fact, this pattern is used in a few places I've seen (not necessarily with ICollection, but you get the idea):
public class Foo : ICollection
{
protected abstract int Count
{
get;
}
int ICollection.Count
{
get
{
return Count;
}
}
}
I believe your code is as short as it can be. Don't think there is any kind of shortcut out there.
The protected member FooBase.Bar() is not an implementation method of the interface IBar. The interface demands a public Method Bar().
There are 2 ways implementing an interface. Explicit implementation or implicit implementation.
Following is explicit implementation. This method is called if an object of Foo is called through a IBar variable.
bool IBar.Bar()
{
return base.Bar();
}
Defining a public method Bar() is implicit implementation.
To have the compiler satisfied you might override or new the baseclass method as public (not a good advise, if method is protected in baseclass).
new public bool Bar()
{
return base.Bar();
}
The trick is to implement an interface, but not having all interface members as public members in the class.

Categories