public interface IA
{
void DoSomething();
void Calculate();
}
public interface IB
{
void DoSomethingElse();
void Calculate();
}
public class A : IA
{
void DoSomething() { }
void Calculate() {}
}
public class B : IB
{
void DoSomethingElse() { }
void Calculate() {}
}
public class C : IA, IB
{
//How can I implement Calculate() in class B and DoSomething() in class A?
}
How can I avoid duplicate code in class C. Reference: How to simulate multiple inheritance in C#. I don't want to write the full methods again in class C. Thanks for any help.
Assuming that IA.Calculate() is not the same as IB.Calculate() and you therefore can't just make IB inherit from IA, you can implement both interfaces in C by delegating execution on private instances of A and B:
public class C : IA, IB
{
private A _a;
private B _b;
public C()
{
this._a = new A();
this._b = new B();
}
public void DoSomething()
{
this._a.DoSomething();
}
void IA.Calculate()
{
this._a.Calculate();
}
public void DoSomethingElse()
{
this._b.DoSomethingElse();
}
void IB.Calculate()
{
this._b.Calculate();
}
}
Note that you are not achieving multiple inheritance at all. C# has singular inheritance. You are implementing multiple interfaces.
There is absolutely no reason why you cannot implement the interfaces in classes A and B, and then have B derive from A and C derive from B. The method implementations from the interfaces can even be abstract, which forces the child class to do the implementation. If you follow this approach then you can still pass C around as IA or IB simply by casting or using the as keyword.
You can also have interface IB "inherit"1 (implement) IA, which means anything that implements IB must also implement IA.
1 When IB derives from IA it isn't inheritance like it is at the class level, it is actually still implementation. So IB implements IA, it doesn't inherit it.
Related
I have two classes in a namespace and these classes need to call each other like this:
public class A
{
void MethodVisibleToB() {}
}
public class B
{
void MethodVisibleToA() {}
}
I want the methods to not be seen neither from inside the dll nor from outside. I wanted only class A to see B.MethodVisibleToA and only class B to see A.MethodVisibleToA.
I usually restrain visibility of a method with nested classes, but this time it is not possible as well as unnecessarily complex. Can you suggest a way to prevent this methods to be called from outside?
The options I have now are not that good:
make all public (meh),
make all internal and move A and B in another dll (not doable)
Edit: I forgot to mention that the classes are in the same namespace in the same assembly
Solution: I took Mrinal Kamboj's suggestion and implemented the interfaces explicitly:
internal interface IA
{
void VisibleByB();
}
internal interface IB
{
void VisibleByA();
}
public class A : IA
{
void IA.VisibleByB() { }
}
public class B : IB
{
void IB.VisibleByA() { }
}
Event more pervert solution to a pervert problem: this will prevent the two interfaces and relative methods to be accessed from other classes and even subclasses:
public static class ClassAreNotMeantToBeUsedThisWay
{
interface IA
{
void VisibleByB();
}
interface IB
{
void VisibleByA();
}
public class A : IA
{
void IA.VisibleByB() { }
}
public class B : IB
{
void IB.VisibleByA() { }
}
}
Try using an Interface and implement Explicitly as follows:
interface InterfaceA
{
void MethodVisibleToB();
}
interface InterfaceB
{
void MethodVisibleToA();
}
public class A : InterfaceA
{
void InterfaceA.MethodVisibleToB() { }
}
public class B : InterfaceB
{
void InterfaceB.MethodVisibleToA() { }
}
Access as follows:
InterfaceA a = new A();
a.MethodVisibleToB();
InterfaceB b = new B();
b.MethodVisibleToA();
this way method would be available when wrapped up in an interface type, will not be available when not wrapped in an Interface type, but a class type
You can mark the methods as internal
Internal types or members are accessible only within files in the same assembly
See the following example:
public class A
{
internal void MethodVisibleToB() {}
}
public class B
{
A aInstance = new A();
internal void MethodVisibleToA()
{
aInstance.MethodVisibleToB(); // this can only be called by methods that are within the same assembly as B
}
}
Addendum
If you need to access the method from the outside, you can use InternalsVisibleToAttribute in the assembly where A and B are located. Anyway, I'd recommend this for a very restricted scope only, e.g. (unit-)tests. Place this line in any .cs file in your assembly (without an namespace)
[assembly: System.InternalsVisibleTo("MyAssembly.Tests")]
I have below classes and implementation inside same class library
public interface IA
{
}
public class A : IA
{
private IB _ib;
public A(IB ib)
{
_ib = ib;
}
}
public interface IB
{
}
public class B : IB
{
private IA _ia;
public B(IA ia)
{
ia = _ia;
}
}
My question is when, either IA or IB, gets instantiated, will it create any circular dependency when performing dependency injection? If so, how can this be resolved?
Your code will have circular dependency and will throw exception at runtime. You need to refactor your code so that A and B do not have dependencies on each other. You will need to extract a new interface (IC) out of either A or B and refactor your code to something like the following:
public interface IA {
}
public class A : IA {
IC _c;
public A(IC c) {
_c = c;
}
}
public interface IB {
}
public class B : IB {
IA _a;
IC _c;
public B(IA a, IC c) {
_a = a;
_c = c;
}
}
public interface IC {
}
public class C : IC {
}
See Circular Dependency in constructors and Dependency Injection on how to refactor your classes to remove circular references
The short answer is that yes, it will be an issue.
There are solutions for it, and these solutions depend on what DI container/solution is being used.
Even if you solve the issue, it a strong signal that your design is not ideal and should be revised.
In most cases you should be able easily extract a third interface which A and B depend on.
I would like to have interace A. Which will allow objects of type A generate other objects of type A.
I need the same behavior for type B. In my application is true that all B are also A. So I would like B to be derived from A.
This is my try:
public interface A {
A method1();
}
public interface B : A {
overrride B method1();
void otherMethod();
}
Note that override keyword dosn't compile here. The only way to make the project compile is make the interface B look as follows:
public interface B : A {
//A method1(); /* commented out because it is inherired */
void otherMethod();
}
However I would like to promise by interface B, that objects of this type have method to produce other objects of type B.
Implementation of interface B could look like:
class Foo : B {
B metod1();
}
Where I want B metod1() to be implemantation of B method1() from interface B and I also want the same method to be implementation of A method1() from interface A. I expect the same behavior in all classes implementing interface B. So I don't want to implement method1 each time twice for both interfaces.
I am doing this in c# with interfaces. But I believe that similar question could be interesting even with classes and possibly also in Java.
The only way to do this properly is using generics like this:
public interface A<T> where T : A<T>
{
T method1();
}
Then B looks like this:
public interface B : A<B>
{
void otherMethod();
}
And finally, implementing a class would go like this:
public class Bravo : B
{
public B method1() { return null; }
public void otherMethod() { }
}
However, you can use the new keyword to shadow a method in an interface, but this isn't a great idea as it makes it harder to reason about your code as it breaks normal inheritance.
Try this:
public interface A
{
A method1();
}
public interface B : A
{
new B method1();
void otherMethod();
}
public class Bravo : B
{
A A.method1() { return null; }
public B method1() { return null; }
public void otherMethod() { }
}
That sure is possible, use the new keyword here, not the override and implement the overridden interface explicitly.
Edit:
Adjusted the sample based on your comments. You will still need the explicit interface implementation IFoo IFoo.GetData() { return GetData(); }, but this one has no code on its own, since its just calling he implicit implementation public INewFoo GetData() { return new Foo(); }.
Here is an example:
public interface IFoo
{
IFoo GetData();
}
public interface INewFoo : IFoo
{
new INewFoo GetData();
}
public class Foo : INewFoo
{
IFoo IFoo.GetData() { return GetData(); }
public INewFoo GetData() { return new Foo(); }
}
Can we implement interface without overriding some of its method.I heard this is possible in some cases.I came across this question recently while interview.
You can inherit the implementation from a base class, if that's what you were thinking of:
interface IFoo
{
void Bar();
}
class Parent
{
public void Bar() {}
}
class Child : Parent, IFoo {}
If that's not it though, I don't know what you're thinking of.
You can implement an interface in an abstract class, and leave some parts of the interface abstract to implement them in further-derived classes:
interface A
{
void f();
void g();
}
abstract class B : A
{
public void f()
{
Console.WriteLine("B.f()");
}
public abstract void g();
}
class C : B
{
public override void g()
{
Console.WriteLine("C.g()");
}
}
Is there any type-safe, compile-time checked possibilty of referring to values that implement multiple interfaces?
Given
interface A {
void DoA();
}
interface B {
void DoB();
}
I'm able to write code for objects implementing A or B, but not both. So I've to come up with ugly wrappers:
class ABCollection {
private class ABWrapper : A, B {
private readonly A a;
private readonly B b;
public static ABWrapper Create<T>(T x) where T : A, B {
return new ABWrapper { a = x, b = x };
}
public void DoA() {
a.DoA();
}
public void DoB() {
b.DoB();
}
}
private List<ABWrapper> data = new List<ABWrapper>();
public void Add<T>(T val) where T : A, B {
data.Add(ABWrapper.Create(val));
}
}
Is there a trick to write this code more intuitively without losing type-safety (runtime-casts etc.)?
E.g.
private List<A and B> ...
Edit: This is not about having a list in particular - I just wanted to give a "complete" example with the issue of storing such values. My problem is just how to type a combination of both interfaces (like A & B or A and B).
Another more useful example: List<IDrawable & IMovable> ...
You can do parametric polymorphism like that in C#, but not subtype polymorphism. That is, you can create a polymorphic method like:
void Foo<T>(T t) where T : IFoo, IBar
{
t.Foo();
t.Bar();
}
and then you must pass an object whose type is known at compile time to implement both IFoo and IBar.
But there is no way to say
void Foo(IFoo-and-IBar t)
{
t.Foo();
t.Bar();
}
and then pass in a value that is both an IFoo and an IBar. Neat feature, but not one we support.
Well, as Eric Lippert said, there's no IFoo-and-IBar type you can use as a method parameter type.
However, I was playing around with some ideas and came up with an alternate way of using your wrapper class that may be better. I'll leave that up to you (or whoever else might search for this question) to decide:
CLASSES
public abstract class ABWrapper : IA, IB
{
private readonly IA a;
private readonly IB b;
protected ABWrapper( IA a, IB b ) { this.a = a; this.b = b; }
// Implement methods on IA and IB
}
public sealed class ABWrapper<T> : ABWrapper
where T : IA, IB
{
private ABWrapper( T a, T b ) : base( a, b ) { }
public static implicit operator ABWrapper<T>( T t )
{
if ( t == null ) return null;
return new ABWrapper<T>( t, t );
}
}
EXAMPLE
public class AB : IA, IB { }
void Method( ABWrapper x )
{
}
void Main()
{
AB x = null;
Method( (ABWrapper<AB>) x );
}
The icky thing about this is that you need to do a cast to ABWrapper<T> at every call site. You could also create an extension method ABWrapper ToABWrapper<T>(this T t) where T : IA, IB to replace the cast if that would be more preferable.
It would be cool if the compiler could reason that an implicit conversion from AB to ABWrapper exists via implicit conversions to and from ABWrapper<T>. There's probably a very good reason it doesn't try to do that, however.
However, what you gain is the ability to put ABWrapper all throughout your method parameters without needing to genercize the methods.
I'm not clear on why you'd want to do this. If you did, you could declare a base interface:
interface AorB {}
interface A : AorB {
void DoA();
}
interface B : AorB {
void DoB();
}
and store those in the collection. Of course you'd have to is- or as-cast when retrieving (standard extension methods could help here).
It seems to me that this is a possible violation of SRP, and the collection is doing too much. Alternately the interfaces are too finely-grained.