I have a base interface that is inherited by several other interfaces. This interface has one method:
[ServiceContract]
public interface IBase
{
[OperationContract]
List<short> GetShorts();
}
I then, of course, have an inheriting interface:
[ServiceContract]
public interface IUseful : IBase
{
[OperationContract]
List<MyObject> GetMyObjects(MyInput input);
}
I have a class that serves as a generic interceptor for interfaces in order to provide a simple way to call services without extra setup:
public class ServiceInvoker<T> : DynamicObject, IInterceptor
where T : class
{
// ...
public T Client { get { return (dynamic)this; } }
// ...
}
I want to be able to call any service that implements IBase, so I have a class that looks like this:
public class BaseCaller
{
private readonly IBase _base;
public BaseCaller(IBase base) { _base = base; }
public List<short> GetShorts() { return _base.GetShorts(); }
}
I construct BaseCaller basically like this:
var si = new ServiceInvoker<IUseful>();
var bc = new BaseCaller(si.Client);
The problem comes when I make a call to GetShorts and it calls _base.GetShorts:
MissingMethodException
Method 'MyApp.IUseful.GetSubNumbers' not found.
When I hover over _base, I can see the interceptor, and I can see that token_GetSubNumbers exists. I can cast _base to IUseful and call GetMyObjects successfully; I just can't call GetShorts. It looks like Castle isn't implementing IBase. Am I doing something wrong?
This appears to work, so going with it unless someone provides a better solution:
I removed the inheritence of IBase and just use it directly with a ServiceInvoker<IBase>. The services now have to implement IBase directly and expose an endpoint for it, but it works.
Related
In the following sample class "SomeClass" does not implement "ISomeInterface". Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
namespace Test
{
public interface IBaseInterface
{
void DoBaseStuff();
}
public interface IChildInterface : IBaseInterface
{
void DoChildStuff();
}
public interface ISomeInterface
{
void DoSomething(IBaseInterface baseInterface);
}
public class SomeClass : ISomeInterface
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
}
This restriction exists because the ISomeInterface expects that any IBaseInterface will satisfy the contract. That is, if you have the following:
public interface IBase {}
public interface IChildA : IBase {}
public interface IChildB : IBase {}
And an interface that expects IBase:
public interface IFoo { void Bar(IBase val); }
Then restricting this in a derived class as you would like:
public class Foo : IFoo { public void Bar(IChildA val) {} }
Would create the following problem:
IChildB something = new ChildB();
IFoo something = new Foo();
something.Bar(something); // This is an invalid call
As such, you're not implementing the contract you said you would.
In this situation, you have two simple options:
Adjust IFoo to be generic, and accept a T that is a derivation of IBase:
public interface IFoo<T> where T : IBase { void Bar(T val); }
public class Foo : IFoo<IChildA> { public void Bar(IChildA val) {} }
Of course, this means that Foo can no longer accept any IBase (including IChildB).
Adjust Foo to implement IFoo, with an additional utility method for void Bar(IChildA val):
public class Foo : IFoo
{
public void Bar(IBase val) {}
public void Bar(IChildA val) {}
}
This has an interesting side-effect: whenever you call ((IFoo)foo).Bar it will expect IBase, and when you call foo.Bar it will expect IChildA or IBase. This means it satisfies the contract, while also having your derived-interface-specific method. If you want to "hide" the Bar(IBase) method more, you could implement IFoo explicitly:
void IFoo.Bar(IBase val) { }
This creates even more inconsistent behavior in your code, as now ((IFoo)foo).Bar is completely different from foo.Bar, but I leave the decision up to you.
This means, with the second version in this section, that foo.Bar(new ChildB()); is now invalid, as IChildB is not an IChildA.
Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
This is not allowed because of the reasoning I mentioned above, IFoo.Bar expects any IBase, whereas you want to further constrain the type to IChildA, which is not a super-interface of IBase, and even if it were it would not be allowed because it violates the interface implementation, though you could more easily define a second method at that point that does what you want.
Keep in mind that when you implement an interface, you subscribe to a contract, and C# will not let you violate that contract.
This violates the Liskov substitution principle.
ISomeInterface guarantees that the method can be called with any IBaseInterface instance. Your implementation cannot limit that to only accept IChildInterface interfaces.
From MSDN:
When a class or struct implements an interface, the class or struct must provide an implementation for all of the members that the interface defines
This method in the derived
void DoSomething(IChildInterface baseInterface)
Does not have the same signature as the one in the interface:
void DoSomething(IBaseInterface baseInterface)
IChildInterface and IBaseInterface are not the same types. Therefore your derived class does not implement all methods of the interface and you get the compilation error.
For a possible the logic behind having this as a restriction instead of the compiler understanding the inheritance see Liskov's substitution principle as in SLakes answer
You should change some interface to use some type which implements IBaseInterface,
then change the method signatures to use whichever child your SomeClass wants.
public interface ISomeInterface<TSomeChild> where TSomeChild : IBaseInterface
{
void DoSomething(TSomeChild baseInterface);
}
public class SomeClass : ISomeInterface<IChildInterface>
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
If you could do that, then you could do this:
IAnimal cat = new Cat();
IAnimalTrainer dogTrainer = new DogTrainer();
dogTrainer.Train(cat);
An IAnimalTrainer can train any IAnimal. But a DogTrainer can only train Dogs. Thus it's illegal for DogTrainer to implement the IAnimalTrainer interface.
I need some sort of way to mark base interfaces and identify if a class implemented the base interface or its derived interface. c# doesn't allow having 'abstract interface'. Is there any way to do this in c#?
public interface IBaseFoo
{
void BaseMethod();
}
public interface IFoo : IBaseFoo
{
void FooMethod();
}
public class Base
{
}
public class A : Base, IFoo
{
}
public class B : Base, IBaseFoo
{
}
Now in the following method I need to check if the typeCls is implemented the IFoo or IBaseFoo without explicitly specifying types. I need sort of a way to mark the base interface and identify it in the method. (ie: if c# allowed having abstract interface, I could have check if IsAbstract property of interfaces of typeClas)
public bool IsBaseFooImplemented<T>(T typeCls) where T : Base
{
// Here I need to check if the typeCls is implemented the IFoo or IBaseFoo
}
Because IFoo : IBaseFoo, every class implementing IFoo also implements IBaseFoo. But not the other way around, so you can simply check whether typeCls is IFoo.
Do note that changing behavior based on implemented interfaces generally is a design smell that bypasses the use for interfaces in the first place.
//somewhere define
static List<IBaseFoo> list = new List<IBaseFoo>();
public class A : Base, IFoo
{
public A()
{
YourClass.list.add(this);
}
}
public class B : Base, IBaseFoo
{
public B()
{
YourClass.list.add(this);
}
}
//then you can check if a class is IFoo or not.
public bool IsBaseFooImplemented<T>(T typeCls) where T : Base
{
foreach(var c in list )
{
if(typeof(c) == typeCls) return true;
}
return false;
}
I have not tested the code but it should work.
I have the following .
public interface IMyService<T>
where T: BaseModelType
{
Process(T input);
}
public class BaseModelType
{
...some property
}
public class SomeClass : BaseModelType
{
...some properties
}
public ServiceImpl : IMyService<SomeClass>
{
...the properties
}
Then I have a unity container where i register all the implementations of the generic interface. I want to be able to use the unitycontainer's resolve method to get the interface, then do some work on it. At the time when i want to use the Resolve method i have the type in runtime
new UnityContainer.Resolve(myTypeVar)
Can I somehow cast this to be
IMyService<BaseModelType> value = new UnityContainer.Resolve(myTypeVar) //want to cast it here from object.
So that i can call the Process method that the interface defines.
No, because IMyService<SomeClass> does not implement IMyService<BaseModelType>. If you look at the implementation of the Process method:
public void Process(SomeClass input){...}
This clearly assumes that you're giving it a SomeClass. It should be able to safely access any members of SomeClass. But if you called this method with a BaseModelType as the parameter, that wouldn't work, would it?
Assuming that you know at runtime that your input argument is going to be of the right type for the given generic IMyService<T> interface, you have two options:
Invoke the generic method signature via reflection. A little slow, but effective.
Add a non-generic parent interface for IMyService, which takes a BaseModelType. In your service implementations, you can implement this method by casting the input to the expected type for that implementation. This requires more code. But you could alleviate that somewhat by having a generic abstract base class that implements this method so the other implementations don't have to.
void Main()
{
var s = (IMyService)new ServiceImpl();
s.Process(new SomeClass());
}
public interface IMyService
{
void Process(BaseModelType input);
}
public interface IMyService<in T> : IMyService
where T: BaseModelType
{
void Process(T input);
}
public class BaseModelType{}
public class SomeClass : BaseModelType{}
public abstract class ServiceBase<T> : IMyService<T>
where T: BaseModelType
{
void IMyService.Process(BaseModelType input)
{
Process((T)input);
}
public abstract void Process(T input);
}
public class ServiceImpl : ServiceBase<SomeClass>{
public override void Process(SomeClass input){}
}
I was wondering if there's a way to accomplish the following:
In my project, I have defined an interface, let's say IFruit. This interface has a public method GetName(). I also declare an interface IApple which implements IFruit and exposes some other method like GetAppleType() or something. There are more fruits like IBanana, ICherry, whatever.
Now on the outside, I want only to be able to use the actual fruit implementations and not IFruit itself. But I cannot declare the IFruit interface as private or internal, since the inherited interfaces will then say "cannot implement because the base class is less accessible".
I know this is possible with abstract implementations, but that's not an option in this case: I really need to use interfaces. Is there such an option?
Update
I guess my example need some clarification :) I use MEF to load interface implementations. The loaded collections are based upon IApple, IBanana, ICherry, etc. But IFruit itself is useless, I can't use classes based on only that interface. So I was looking for a way to prevent other developers from implementing solely IFruit, thinking that their class will be loaded (which it won't). So basically, it comes down to:
internal interface IFruit
{
public string GetName();
}
public interface IApple : IFruit
{
public decimal GetDiameter();
}
public interface IBanana : IFruit
{
public decimal GetLenght();
}
But that won't compile due to the less accessible base interface.
One way that you can guarantee this doesn't happen unintentionally is to make IFruit internal to your assembly and then use some adaptor to wrap the type appropriately:
public interface IApple { string GetName(); }
public interface IBanana { string GetName(); }
internal interface IFruit { string GetName(); }
class FruitAdaptor: IFruit
{
public FruitAdaptor(string name) { this.name = name; }
private string name;
public string GetName() { return name; }
}
// convenience methods for fruit:
static class IFruitExtensions
{
public static IFruit AsFruit(this IBanana banana)
{
return new FruitAdaptor(banana.GetName());
}
public static IFruit AsFruit(this IApple apple)
{
return new FruitAdaptor(apple.GetName());
}
}
Then:
MethodThatNeedsFruit(banana.AsFruit());
You could also easily extend this to lazily call GetName on the adapted object, if the name could change over time.
Another option could be to have a DEBUG-only check that does load all IFruit implementers, and then throws an exception if one of them doesn't actually implement IBanana/IApple. Since it sounds like these classes are for internal use inside your company, this should stop anyone from accidentally implementing the wrong thing.
It isn't really possible to do what you're trying, but you can put people off using the IFruit interface with an [Obsolete] attribute, with message to say why.
On your IBanana, IApple, ... interfaces, disable the obsolete warning from appearing.
[Obsolete]
public interface IFruit {
...
}
#pragma warning disable 612
public interface IBanana : IFruit {
...
}
#pragma warning restore 612
If you have somewhow in your code (assuming that I correctly understand your state), something like this:
public class WaterMellon : IFruit, IVegetables...
{
}
and you want to be able to consumer of your framework access only to a methods of IFruit, there is no other known method to me then simply cast.
IFruit fruit = new WaterMelon();
fruit. //CAN ACCESS ONLY TO FRUIT IMPLEMNTATION AVAILABLE IN WATERMELON
If this is not what you're asking for, please clarify.
interface IXXX
{
void Foo();
}
class XXX : IXXX
{
public static void Foo()
{
Console.WriteLine("From XXX");
}
}
class Program
{
static void Main(string[] args)
{
XXX.Foo();
}
}
Compiler error: XXX.Foo() cannot implement an interface member because it is static.
Why can't a static method implement an interface method?
See this thread from JoelOnSoftware describing the reasons behind this.
Basically the interface is the contract between the consumer and the provider, and a static method belongs to the class, and not each instance of the class as such.
An earlier question on SO also deal with the exact same question:
Why Doesn't C# Allow Static Methods to Implement an Interface?
An interface defines the behaviour that an object must respond to.
As Foo is a static method, the object doesn't respond to it. In other words, you couldn't write...
XXX myXXX = new XXX();
myXXX.Foo();
In other words, myXXX doesn't fully satisfy the requirements of the interface.
IF we look at interfaces as a promise that an object can perform the methods listed in the interface, then ths idea of static implementation becomes problematic. If the implemetion is static, then you can't write new ImplementingObject().ImplementedMthod. The object can't perform the method, the class can.
You use interface to avoid using concrete class during instantiation. You can't access static method through instantiated class, so implementing interface methods with static methods is not allowed.
Well, I believe it should allowed in case of generic type parameter. It probably simplified contractual singleton class. Here is an example:
public interface IEntity {
// some constrains...
DataRow ObjToRow(object obj);
object RowToObj(DataRow dr);
}
//T would be any class inherites from IEntity with default contructor signature.
public interface IMyContract {
T read<T>() where T : IEntity;
void write<T>(T object) where T : IEntity;
}
//everything in the class is static
public static class SqlProvider : IMyContract {
public static T read<T>() where T: IEntity {
DataRow dr = [reading from database]
return T.RowToObj(dr);
}
//compile error here....
public static void write<T>(T obj) where T : IEntity {
DataRow dr = T.ObjToRow(obj);
[ ... commit data row dr to database ... ]
}
}
public static class MyAppleEntity : IEntity {
[... implement IEntity contract normally ... ]
}
public static class MyOrangeEntity : IEntity {
[... implement IEntity contract normally ... ]
}
public class MyTest {
void reading() {
MyAppleEntity apple = SqlProvider.Read<MyAppleEntity>();
MyOrangeEntity orange = SqlProvider.Read<MyOrangeEntity>();
SqlProvider.write<MyAppleEntity>(apple);
SqlProvider.write<MyOrangeEntity>(orange);
}
}
The only time a type reference implicitly is in the SqlProvider.read() and write() and T is well identity at point of invoke. Without static implementation of interface I'm forced to write like this.
public class MyAppleEntity : IEntity {
[... implement IEntity contract normally ... ]
}
.....
public T read<T>() where T: IEntity, new() {
DataRow dr = [reading from database]
return new T().RowToObj(dr);
}
Very little different but not quite as elegant.
Because interface member are public and overridable, and that static method cannot by design be overrided or abstract, Interfaces are here to define an accessible contract that must be implemented by their concrete implementation (with as many steps of abstract implementations & inherited interfaces between) and as far as I know there is no way to create an abstract static method.