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.
Related
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.
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
In C# I'm in a scenario with the following types provided by the environment:
public interface IFoo {
}
public abstract class Base {
}
public class Derived : Base, IFoo {
}
public class Arbitrary {
public Base GetBase() { }
}
Here's what I've written in addition to this. Note that I can guarantee in my code that Arbitrary.GetBase() will always return an instance of Derived.
public class Arbitrary2 : Arbitrary {
public IFoo GetDerived() {
return (IFoo)base.GetBase();
}
}
However this code fails with the message "Cannot convert type 'Base' to 'IFoo'".
But if I do this then it works:
public class Arbitrary2 : Arbitrary {
public IFoo GetDerived() {
Object baseAsObject = base.GetBase();
return (IFoo)baseAsObject ;
}
}
Why is this upcast to Object necessary before I downcast it to IFoo? The two pieces of code are functionally identical, and the latter will reliably crash at runtime if the cast is invalid. I don't understand why the compiler complains.
You don't need to do this. Your code should work, as is. See this program for details:
using System;
public interface IFoo { }
public abstract class Base { }
public class Derived : Base, IFoo { }
public class Arbitrary {
public Base GetBase() { return new Derived(); }
}
public class Arbitrary2 : Arbitrary {
public IFoo GetDerived() {
return (IFoo)base.GetBase();
}
}
class Program
{
static void Main(string[] args)
{
Arbitrary2 test = new Arbitrary2();
IFoo check = test.GetDerived();
Console.WriteLine(check.GetType().Name);
Console.WriteLine("Press key to exit:");
Console.ReadKey();
}
}
Your GetBase() method returns Base, which does not implement IFoo.
Base can't be converted to IFoo because Base doesn't have anything to do with IFoo:
public abstract class Base { }
Based on this declaration, there could very well be instances of Base which aren't of type IFoo. Indeed, based on this declaration the compiler has absolutely no reason to assume that any given instance of Base would ever implement IFoo.
Derived implements IFoo:
public class Derived : Base, IFoo { }
But you're not returning a Derived, you're returning a Base. By polymorphing it through Object you're effectively "tricking" the compiler. You're telling it that you know more than it does and it should listen to you. This can be fine, as long as you do in fact know more than the compiler does. And what you know that the compiler doesn't know is that every instance of Base is going to be able to polymorph to IFoo.
In that case, why not just implement IFoo on Base? That way you'd be sharing your knowledge with the compiler and everyone will be happy.
The reason the compiler disallows the explicit cast is that Base doesn't implement IFoo.
If you can guarantee that GetBase() will always return a Derived, then you can just insert a cast to Derived prior to the IFoo cast:
public class Arbitrary2 : Arbitrary {
public IFoo GetDerived() {
return (IFoo)(Derived)base.GetBase();
}
}
Of course this will throw at run-time if you're mistaken. Alternatively, you can use an as cast will just return null if it fails:
public class Arbitrary2 : Arbitrary {
public IFoo GetDerived() {
return base.GetBase() as IFoo;
}
}
Arbitrary.GetBase() returns an instance of Base. Base's hierarchy does not contain IFoo.
At runtime, yes, your object is a Derived instance, but based on what the compiler knows--class relationships--there isn't a connection and therefore a way to cast from Base to IFoo as you are trying in your first method.
Can't you just write
public class Arbitrary2 : Arbitrary {
public IFoo GetDerived() {
return (Derived)this.GetBase();
}
}
The compiler will see the connection between Derived and Base, so the explicit cast to Derived ought to be OK. Then any Derived is surely an IFoo, so there's no need to cast an additional time (that conversion is implicit).
Don't use the base. keyword. Either say this. (as above) or leave out.
EDIT: Also, your original code did compile, but my version might be a bit easier to read.
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.
Interface methods in C# can be implemented explicitly, so that their implementation is invoked when an instance is explicitly cast to the interface type. Why is this not also supported on virtual methods of classes?
Although working around the 'multiple inheritance' issue is unique to interfaces, it seems that for every other reason that explicitly implemented members would be useful for interfaces, they would also be useful for virtual methods. A cleaner return-type covariance model springs to mind.
Edit: By request, an example:
public class Foo {
...
}
public class Bar : Foo {
...
}
class Base {
abstract Foo A ();
}
class Dervied {
private Bar _b;
Bar A () {
return _b;
}
Foo Base.A () {
return _b;
}
}
I am aware of using helper methods to simulate this, but the net effect seems to have any of the bad characteristics that explicit implementation would have, but with a dirtier API. The crux of my question is not how to do return type covariance, but why a similar mechanism for interfaces is not supported for virtual methods.
Some people recommend not having public virtual methods in the first place. But instead create one public non virtual method representing the consumer interface, and one protected virtual method representing the implementer interface.
I would not call separating the contracts for caller and implementer "muddying the design". In many cases it's cleaner IMO, but I'm usually too lazy to actually do it that way.
This design works much better with return type covariance and method hiding.
An additional benefit of this is that the public wrapper can add additional checking code and supports different contracts for the caller and implementer.
An example of how I'd emulate return type covariance:
public class Base
{
protected virtual Base FooOverride(int i){return new Base();};//FooOverride does not need to duplicate the argument checking
public Base Foo(int i)
{
if(i<0)
throw new ArgumentException("i<0");
return FooOverride(i);
}
}
public class Derived:Base
{
protected override Base FooOverride(int i){return new Derived();};
public new Derived Foo(int i)
{
return (Derived)base.Foo();
}
}
What benefit would that have, besides from allowing something like this?
class Base
{
virtual void M() { }
}
class Derived : Base
{
override void M() { }
override void Base.M() { }
}
This effectively bakes a violation of the Liskov Substitution Principle into the C# language - if I have a variable of type Base, calling M() on it can do entirely different things depending on whether the run-time type is Base or Derived.
Explicit interface implementation is different. Say you have this:
interface IFoo
{
void DoStuff();
}
interface IBar
{
void DoStuff();
}
class C : IFoo, IBar
{
void IFoo.DoStuff() { }
void IBar.DoStuff() { }
}
This preserves the LSP - if I have an IFoo variable that happens to be of run-time type C, calling DoStuff() on it will get the IFoo implementation of it. Likewise with IBar.