Why must an C# interface method implemented in a class be public? - c#

I have a class which inherits an interface. An interface member method is implemented in my class without an access modifier (so, by default it's private ) .
I am getting the error "cannot implement an interface member because it is not public".
Why it is not allowed? Can't I override the accessibility?

Here's an example of why it doesn't make sense to be able to override the visibility:
interface someI
{
void doYourWork();
}
public class A : someI
{
public void doYourWork()
{
//...
}
}
public class B : someI
{
private void doYourWork()
{
//...
}
}
void Main()
{
List<someI> workers = getWorkers();
foreach(var worker in workers)
worker.doYourWork();
}
What happens when your worker is of type B? You're calling a method as if it were public, but it's a private method. If you want this functionality, then it's not really a private method is it?
If you only want it to be public when referenced through your interface, then you can define it as such:
public class B : someI
{
void someI.doYourWork()
{
//...
}
}
And you end up with this:
var b = new B();
b.doYourWork(); // Not accessible
((someI)b).doYourWork(); // Accessible

Methods have to be implemented public because they have to be callable through the interface, thus from where the interface is accessible as a type.
You have a few options here to "change" the visibility of that method. Given:
public interface IFoo
{
bool IsFoo();
}
A. Implement the method explicitly
public class Foo : IFoo
{
bool IFoo.IsFoo() { return true; }
}
The method will only be available through the interface (IFoo in this case.)
B. Change the visibility of the interface
Define the interface as internal instead of public. As a consequence, however, Foo will have to be internal too.

Requiring that an interface implementation be public is simply a logical requirement. When you implement an interface, you're telling the compiler "Hey I implement every method on this interface". So making the method private makes it no longer accessible - and logically not implemented. Interfaces serve as a contract to code that uses your object saying you can always call any method defined in the interface on my object. If the implementing method were private, that would not longer be true.
If you want to hide your implementation from, say Intellisense, then you can simply implement the method explicitly as #Bryan mentions.

Related

How to mock an abstract class using the decorator pattern and containing a constructor that takes an instance of itself

First, I want to clarify that this question is not a dup of this because the situation is different when you have an abstract class.
My situation is that there exists a base class
public abstract class FooBase
{
public FooBase(FooBase inner) { /* ... */ }
public virtual void DoSomething() { /* ... */ }
}
which is in a different assembly and I want to mock the behavior of DoSomething(). The problem is that if I try to create a mock
public class MockFoo : FooBase
{
public MockFoo(...) : base(/*I have to put a FooBase in here*/) { /* ... */ }
}
I can't pass a new MockFoo() into base because it'll cause an infinite recursion. Any other ideas I have (such as creating another MockFooOuter) can't get around the infinite recursion problem.
I agree with Nkosi. You need to pass any (like suggested null) value to base that will not cause the exception in FooBase constructor.
If you want to test a decorator you don't have to mock the decorated method DoSomething but the whole decorated class.
First of all you have to fix your class design and Decorator implementation:
right now the decorator accepts an instance of his own decorator type in the constructor which doesn't make sense. If it is a decorator it must accept an instance of the decorated type instead.
This means you have to introduce an interface for all the decorated types to implement. In this example it's named IDecorated.
The goal is to have a unit test that looks like this:
public class UnitTest
{
public void TestDecorator()
{
IDecorated mockOfIDecorated = new DecoratedMock();
DecoratorBase decoratorBaseTest = new DecoratorBaseTest(mockOfIDecorated);
// Use decoratorBaseTest instance to test its public members
}
}
To make mocking possible introduce an interface of the decorated type:
public interface IDecorated
{
void DoSomething();
}
This will change and fix the signature of the constructor of the decorator type. Also don't make the implementation of the decorator's DoSomething virtual as this can lead to undesired behavior (e.g. the extending class forgets to delegate calls to the decorated type instance). Therefore the virtual has been removed. To make the extended behavior overrideable for subtypes just add an abstract method:
public abstract class DecoratorBase : IDecorated
{
private IDecorated decorated;
// The decorator should always accept an abstract type
// or interface of the type to be decorated
public DecoratorBase(IDecorated decorated)
{
this.decorated = decorated;
}
public void DoSomething()
{
// Delegate calls to the decorated class instance and ...
this.decorated.DoSomething();
// ... add functionality by invoking additional members.
// Making this member abstract adds customization for subtypes
DoSomethingToExtendTheDecoratedBehavior();
}
public object DoSomethingDecoratorSpecific()
{
}
protected abstract void DoSomethingToExtendTheDecoratedBehavior();
}
Since you cannot test an abstract class directly you need to provide a test implementation which can be instantiated by the test class:
public class DecoratorBaseTest : DecoratorBase
{
public DecoratorBaseTest(IDecorated mockOfIDecorated) : base(mockOfIDecorated) { /* ... */ }
#region Overrides of DecoratorBase
protected override void DoSomethingToExtendTheDecoratedBehavior()
{
// Do nothing here because the unit test
// tests only public members of DecoratorBase
}
#endregion
}
The mocked type of IDecorated. Invoking DoSomething() on this type does nothing:
public class DecoratedMock : IDecorated
{
#region Implementation of IDecorated
public void DoSomething()
{
// Do nothing since this is a mock
}
#endregion
}
Now that the Decorator implementation is fixed, you can easily test the decorator class.

OOP Design: Concrete Class having different Operations with Same Base Class

I am wondering if the following code can be written in C#:
AbstractClass a = new ConcreteClass1();
a.Operations.Method1();
AbstractClass b = new ConcreteClass2();
b.Operations.Method2();
where Method1() is exclusive to the ConcreteClass1 instance and Method2() is exclusive to the ConcreteClass2() instance. As a result, a.Operations.Method2() and b.Operations.Method1() would be invalid.
This is not possible by design - a and b have the same type, and the compiler will treat them as such. The only way to make it work is by using runtime exceptions.
The concept behind using abstract classes or interfaces conflicts with what you are attempting to do; it sounds like ConcreteClass1 and ConcreteClass2 do not server the same purpose, should they still use the same abstract base class?
I don't know what exactly you are trying to do - so I'll provide a few options:
Use interfaces to show that specific classes implement specific operations:
interface IOperation1
{
void Operation1();
}
interface IOperation2
{
void Operation2();
}
Then reference the interfaces based on what you are trying to achieve.
If Method1 and Method2 are supposed to be invoked at the same time, consider a design where AbstractClass declares the method to be invoked, and the concrete classes do different operations based on that:
abstract class AbstractClass
{
...
abstract void DoSomeOperation();
}
class ConcreteClass1
{
override void DoSomeOperation()
{
this.Operations.Method1();
}
}
class ConcreteClass2
{
override void DoSomeOperation()
{
this.Operations.Method2();
}
}
It's okay for ConcreteClass1 and ConcreteClass2 to have some different methods, but share some functionality that they both inherit from AbstractClass. (If you cast them as their base type then you can only call common methods that they inherit from the base type.)
It sounds like the difference between whether a concrete class uses Method1 or Method2 is an internal detail that should be handled inside the class. The class should know what method it needs to call. In fact, does a consumer of that class even need to know that it depends on Operations? Probably not. Consumers should just call a method on the class, and then whether that class uses Operations.Method1, Operations.Method2, or even depends on Operations at all is an internal implementation detail.
Maybe what you want is something like this:
public abstract class AbstractClass
{
public abstract void DoSomething();
}
public class Operations
{
public void Method1()
{
//Does something
}
public void Method2()
{
//Apparently does something comopletely different
}
}
public class ConcreteClass1 : AbstractClass
{
private Operations _operations;
public override void DoSomething()
{
_operations.Method1();
}
}
public class ConcreteClass2 : AbstractClass
{
private Operations _operations;
public override void DoSomething()
{
_operations.Method2();
}
}
Operations should only be in the base class if it's required that every derived class will use it. (That doesn't happen too much. If all of the derived classes have the same behavior, why isn't it in the base class?) If that's the case then you can hide it in the base class, like this:
public abstract class AbstractClass
{
private Operations _operations;
protected Operations Operations { get { return _operations; } }
public abstract void DoSomething();
}
That way it's exposed to the derived classes but hidden from everything else.

c# runtime polymorphism with abstract base class

I am trying to clean up an existing code base, and am having trouble with using a generic reference name to the different derived classes of an abstract class.
For instance:
public abstract class Base<T> : Utilities.CommonRequiredObject
{
protected List<T> RawContents = new List<T>();
.
.
public abstract void LoadContents(List<T> Contents); // Each Class needs to load and process differently
protected List<T> Contents;
public virtual void DoSomething() // Default here for common use. Defined in Each class for its specifics (if needed)
{
...
}
public abstract List<T> FunctionToGetContents();
}
public class FOO : Base<string>
{
public override void DoSomething() ...
public override List<string> FunctionToGetContents() ...
}
public class BAR : Base<byte>
{
public override void DoSomething() ...
public override List<byte> FunctionToGetContents() ...
}
Main Logic to try to use common variable. I want to create a new class to use, but want to use it then in a runtime polymorphic way. As the classes have the common functionality, and have overrides where needed, I want to be able to create an instance, and then use it:
IE: Base<T> ObjectToUse;
This way, I can simply refer to the ObjectToUse in the following code and call common methods. As I inherited some common routines from another base class, I am not sure if I can use an interface or not.
if(variable)
{
FOO ObjectToUse = new FOO();
}
else
{
BAR ObjectToUse = new BAR();
}
ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...
Edit:
Based on the comments I received quickly (thanks again everyone) would it be better than to remove the Generic (Base<T>) and have the classes all of type Base(), then I could define the ObjectToUse simply as Base ObjectToUse; I believe.
This cannot be done.
By utilizing a reference that requires a generic type parameter, you must give it one. You could utilize dynamic here so that the type is run-time evaluated, but thats the best you will get.
Even utilizing something like a template method pattern, you would need to specify the generic type argument. If you just want the DoSomething method for this, it would need to be promoted to a higher base class (or an interface) so you could hold a reference to that type, and call that (non-generic) function.
To your comment, the solution I would take is this; refactor the common code into a template method pattern within the base class. Then have the "triggering" function be a non-generic inherited member from a non-generic base class (or interface). Now, you can hold a reference to that type, and invoke the template method to cause the other calls to occur.
public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
LoadContents(FunctionToGetContents());
DoSomething();
}
Then:
IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();

Interface inheritance consistency

First look at this code:
class Program
{
static void Main(string[] args)
{
var x =(Base) new Derived();
((IMethod)x).DoWork();
Console.ReadKey();
}
}
interface IMethod
{
void DoWork();
}
abstract class Base : IMethod
{
void IMethod.DoWork()
{
Console.WriteLine("Base.DoWork");
}
}
class Derived : Base, IMethod
{
public void DoWork()
{
//here I where I want to call base.DoWork();
Console.WriteLine("Derived.DoWork");
}
}
Output:
Derived.DoWork
Desired:
Base.DoWork
Derived.DoWork
I'm dealing with an API that exposes an interface that when implemented, the DoWork method will be called at some part of the procession.
Now in the above example, the class Base is a part of the API, that internally (in the API) already explicitly implements that interface and does some important executions in the DoWork method.
I need to override the implementation of the IMethod in my derived class as well, so I get notified when needed, the problem is I can't 'override' the method and call the base method, neither can I cast base to IMethod.
Any solution?
Note: reflection won't work since it's a Silveright project, and private method invoking is prohibited.
Are you able to just compose the classes, rather than using inheritance? Then you can implement DoWork() however you like, and still call DoWork() on the Base object as well. Since Base is abstract, you'll need to derive a dummy type to get everything to work.
class Derived : IMethod
{
private class SneakyBase : Base
{
// abstract implementations here
}
private IMethod baseObject = new SneakyBase();
void DoWork()
{
baseObject.DoWork();
// Custom DoWork code here
}
}
It's obviously a bit of pain to do things this way, but the API designers made an odd choice with the explicit interface implementation, and you're now paying for it.
Are you looking for:
public class Derived : Base
{
public override void DoWork()
{
base.DoWork();
}
}
I've found DanBryant's comment to be the answer, although as he mentions is a bit risky since we can't assure the implementer will call the base method, but is a decent way tho.
I made a protected virtual method that is called from the private interface implementer, then, in the derived class, instead of worrying about the interface, I just care about overriding the base class and calling the base implementation from it, that works perfect, example:
abstract class Base : IMethod
{
void IMethod.DoWork()
{
DoWork();
}
protected virtual void DoWork()
{
Console.WriteLine("Base.DoWork");
}
}
class Derived : Base
{
protected override void DoWork()
{
base.DoWork();
//here I where I want to call base.DoWork();
Console.WriteLine("Derived.DoWork");
}
}

Creating a generic interface in C#

I know that the title may be confusing (or even misleading), but I'm planning to create an interface which is generic, and it should implement a method involving a generic parameter.
When implemented in class AFirst, it should have a method MyMethod<A>() that returns the type A, and when implemented in class BFirst, it should have a method MyMethod<B>() that returns type B. I need this functionality as there is an inheritance relationship between A and B (and MANY others) and I need a generic method that I can call with any of the base classes.
If it was confusing, have a look at what I want to do:
Consider B derives from A.
Consider AFirst and BFirst implement IMyInterface<A> and IMyInterface<B> respectively:
BFirst mySecondObj = new BFirst();
A myA = BFirst.MyMethod<A>();
B myB = BFirst.MyMethod<B>();
I need access to the MyMethod templates for the base classes to, so when I instantiate the BFirst instance, I can call either MyMethod for A or B. I'm building a template system and think these AFirst and BFirst are the templates, and MyMethod acts like a factory method. I will have a big hierarchy, and the project needs to be extensible by deriving even more classes from my base class A, so I can't just create seperate interfaces or methods for each of them.
I tried this:
interface IMyInterface<T> where T : A
{
T GetNewInstance<T>();
}
and I tried to implement this way, but I'm getting it as created like this when I click implement:
class AFirst : IMyInterface<A>
{
public T GetNewInstance<T>()
{
throw new NotImplementedException();
}
}
Didn't make sense to me in the way that I've specified the T type to be A, but it still implements as T. For example, it will go like this (below is how I want it to happen)
class AFirst : IMyInterface<A>
{
public A GetNewInstance<A>()
{
throw new NotImplementedException();
}
}
class BFirst : AFirst, IMyInterface<B>
{
public B GetNewInstance<B>()
{
throw new NotImplementedException();
}
}
and from outer code, call the sample as in the beginning of my question:
BFirst myBFirst = new BFirst();
A a = BFirst.GetNewInstance<A>(); //calls AFirst's method and returns A
B b = BFirst.GetNewInstance<B>(); //calls BFirst's method and returns B
How is this possible?
Thanks,
Can.
In your generic interface you define a generic method. I think that's where the confusion is. It should be a normal method that returns your generic type. I.e.
interface IMyInterface<T> where T : A
{
T GetNewInstance();
}
This will get implemented as
class AFirst : IMyInterface<A>
{
public A GetNewInstance()
{
throw new NotImplementedException();
}
}
which I'm guessing is what you want.
You are possibly over complicating this. You could consider a Template pattern. The base class is abstract and defines an overridable method. Classes inheriting from this base class then provide implementations of this method.
You can still use generics and an interface but this pattern is probably the basis you would need to start from.
Edit:
public abstract class ABase<T>
{
public abstract T MyMethod();
}
public class A : ABase<A>
{
public override A MyMethod()
{
throw new NotImplementedException();
}
}
public class B : A
{
}
And to implement an interface, this would be
public interface IHasMethod<T>
{
T MyMethod();
}
public abstract class ABase<T> : IHasMethod<T> ...

Categories

Resources