In what scenarios would somebody pass (or receive) an interface as a parameter? Is it really a useful thing or just a fancy way of doing something?
It's an extremely useful thing.
Take any of the LINQ extension methods, for instance. They don't care what's passed to them, as long as it implements IEnumerable<T>. The idea is that they can all be applied to anything that you can enumerate over using a foreach loop.
Imagine how pointlessly restrictive it would be if they all required you to pass T[] arrays, or List<T> objects, for example.
Here's just one very trivial illustration. Let's pretend the LINQ extensions don't exist (which is actually a real possibility if I'm using .NET 2.0) and I want to write a Sum method.
I could write it like this:
public static double Sum(List<double> values)
{
double sum = 0.0;
foreach (double value in values)
{
sum += value;
}
return sum;
}
That's all well and good, but notice something here: I wrote the method to take a List<double>, which is a class that has far more functionality than this code depends on. Where does it use Insert? Where does it use RemoveAt? FindAll? Sort? Nope, none of that is required. So is it really necessary that this method get passed a List<double>?
Moreover, say I have a double[]. Theoretically, I should be able to pop that right in as the values parameter, since all I'm doing is enumerating over it using a foreach; but since I've typed values as List<double>, to pass a double[] to my Sum method I'd have to do this:
double sum = Sum(new List<double>(myArray));
That's just a completely unnecessary new object I've constructed simply to call code that really should've been able to handle my original object in the first place.
By writing methods that take interfaces as parameters, you make your code more flexible and more powerful, and you avoid imposing inappropriate restrictions (give me an X, even though I could just as easily do this with a Y) on calling code.
The easiest way to remember, is that it's all about programming to the interface, not the implementation. Say for instance, I have a method where I want to do something, e.g.
public void MakeNoise(IAnimal animal)
{
animal.MakeNoise();
}
I don't care what the specific implementation is, I just know that whatever is passed in, I can call MakeNoise(). I program to an interface, not an implementation.
public class Dog : IAnimal
{
public void MakeNoise()
{
Console.WriteLine("Woof");
}
}
public class Cat : IAnimal
{
public void MakeNoise()
{
Console.WriteLine("Meow");
}
}
Interface programming is a core aspect of OOP, you'll find them incredibly useful.
Whenever you need abstraction.
One good example is the IEnumerable<T> and IQueryable<T> interfaces in the .NET Framework. They allow you to write Extension Methods that can be used against List<T>, Dictionary<TKey, TValue>, or even T[].
You could also take Dependency Injection for example. In ASP.NET MVC, it is common to use Repositories for Data Access:
public class MyClassRepository
{
public MyClass GetById(int id)
{
// Some Implementation
}
}
public class MyController
{
private MyClassRepository _repo;
public class MyController() : base(new MyClassRepository()) { }
public class MyController(MyClassRepository repo) { _repo = repo; }
}
Now, if you want to Mock that Repository for Unit Testing...you're boned. There's no easy way. In comes Interfaces!
public interface IMyClassRepository
{
public MyClass GetById(int id);
}
public class MyClassRepository : IMyClassRepository
{
public MyClass GetById(int id)
{
// Some Implementation
}
}
public class MyController
{
private IMyClassRepository _repo;
public class MyController() : base(new MyClassRepository()) { }
public class MyController(IMyClassRepository repo) { _repo = repo; }
}
Now with the introduction of an Interface, we are free to mock IMyClassRepository however we see fit for testing purposes. Usually this involves a simple mock object with specified behavior to product reliable results.
Interfaces are very useful.
They help with decoupling your code - for example, if you use the IList interface and pass that in to your method and use it in your method, you can pass in any collection that implements this interface, whether it is in the BCL or not.
One area where interfaces would make good sense is if you are using a design pattern approach.
For instance, the Observer pattern, or the Proxy pattern, the Visitor pattern, and others. You probably could choose not to use an interface, but I'd imagine that you'll quickly decide that the code becomes much cleaner (as in more modular, concerns-separated) than a non-interfaced code. It just helps promote better code, in these situations.
Polymorphism!
They help you write code that doesn't discriminate against certain classes just because they don't inherit from a special base class. Your functions will be equal-opportunity executors.
Related
I have an interface which I am mocking with 'NSubstitute' which contains properties that return concreate classes, that is the return value is not an interface. e.g
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
The 'SomeObj' concrete class has a default constructor but 'NSubstitute' always returns 'null' for these properties. The class itself is not under my control so I cannot simply make it derive from an interface.
Can 'NSubstitute' mock these type of properties? Or is there a way to override the behaviour? Otherwise I have to manually initialise the mock before the test and that can be a lot of code (even if its reused through a common method).
Perhaps there is a simpler solution that I have over-looked?
Classes will be auto-mocked if they have a default (parameterless) constructor and all its members are virtual (see the note in the intro of Auto and recursive mocks). The aim of this is to reduce the potential for unwanted (destructive?) side-effects if we are using a substitute and suddenly hit a non-virtual, unmocked code path that does bad stuff in an instance we thought was fake.
NSubstitute doesn't have a way override this behaviour. Instead, I'd recommend creating all your substitutes via your own factory method (e.g. a static Sub.For<T>(...) method in your test project) that uses NSubstitute to produce a substitute, then applies all the specific initialisation rules you need, like using reflection to stub out values for each class property.
Hope this helps.
Possibly related links:
I advise trying to avoid mocking types we don't own.
Stack Overflow: Is it recommended to mock concrete class?
Hacky factory method sample that subs properties using reflection.
It doesn't count as auto-mocking but you did also ask "Or is there a way to override the behaviour?" and "Perhaps there is a simpler solution that I have over-looked?"
This answer relies on the statements in your question that:
SomeObj is a class outside of your control, from which I assume it is either separately tested or else not testable
SomeObj has a default constructor
Sure, it requires you to "manually initialise the mock before the test" but since you've not told us what this object is it's not possible to know how much work it would take to implement fully.
public class SomeObj
{
// Non-virtual to prevent auto-mocking
public void Dummy() { }
}
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
[TestMethod]
public void Test_17182355ms()
{
ISomething mockedSomething = Substitute.For<ISomething>();
SomeObj firstObj = mockedSomething.First;
Assert.IsNull(firstObj);
mockedSomething.First.Returns(new SomeObj());
mockedSomething.Second.Returns(new SomeObj());
firstObj = mockedSomething.First;
Assert.IsNotNull(firstObj);
}
Another approach, though not without its own drawbacks, would be to extract your own interface for SomeObj, something like this:
public interface ISomeObj
{
void Dummy();
}
public class MySomeObj : SomeObj, ISomeObj
{
}
and then mock ISomeObj in your test.
Is it possible to declare a generic collection to hold only objects implementing a generic Interface with any <T>?
My question burns down to: If I want to/have to store objects implementing a generic interface, is there a better way to express that fact than using a non generic collection or (generic of <Object>).
Example:
// An example Generic Interface
interface ISyncInterface<T>
{
Task DoSync();
IEnumerable<T> NewItems { get; }
}
// a manager-class that registers different classes implementing
// the generic interface.
// The code works - can it be done better?
class Manager
{
private List<Object> _services = new List<Object>(); // <- works but is basically non generic
// however the RegisterService() ensures that only correct types can be added.
// would like to have something like below to indicate the Interface-Type
// however: this would only allow _services2.Add to hold types of ISyncInterface<Object>
// - ISyncInterface<ServiceA_DTO> would fail.
private List<ISyncInterface<Object>> _services2 = new List<ISyncInterface<Object>>();
void RegisterService<T, U>(T service)
where T : ISyncInterface<U>
{
_services.Add(service); // <- works e.g. for SyncServiceA
// _services2.Add(service); // <- FAILS for SyncServiceA - no conversion
// _services2.Add((ISyncInterface<Object>) service); // <- FAILS also - no explicit cast
}
}
// SETUP - The classes used above. Just to clarify.
class ServiceA_DTO { }
class ServiceB_DTO { }
class SyncServiceA : ISyncInterface<ServiceA_DTO>
{
public Task DoSync() {}
public IEnumerable<ServiceA_DTO> NewItems { get; }
}
class SyncServiceB : ISyncInterface<ServiceB_DTO>
{
public Task DoSync() {}
public IEnumerable<ServiceB_DTO> NewItems { get; }
}
Is this possible at all? Any advice is highly appreciated!
Update: New, more verbose code to clarify the problem.
Below there was a suggestion to base the generic interface on an non generic one. But as a consequence all implementing classes of the generic interface would have to implement the non generic methods, properties etc. - or is there a way around it?
Thanks for your input!
Is it possible to declare a generic collection to hold only objects implementing a generic interface instantiated with any T?
Short answer: no.
Longer answer: no, because that is not useful.
Let's consider a simple generic interface:
interface I<T> { T Get(); }
And a bunch of objects that implement it:
class Lion : I<Lion>
{
public Lion Get() => this;
}
class TaxPolicyFactory : I<TaxPolicy>
{
public TaxPolicy Get() => new TaxPolicy();
}
class Door: I<Doorknob>
{
public Doorknob Get() => this.doorknob;
...
}
OK, now suppose you have a List<I<ANYTHING>> like you want:
var list = new List<I<???>> { new TaxPolicyFactory(), new Lion(), new Door() };
You've got a list with a tax policy factory, a lion and a door in it. Those types have nothing in common with each other; there's no operation you can perform on each of those objects. Even if you could call Get on each of them, then you'd have a sequence with a tax policy, a lion and a doorknob in it, and what are you going to do with that?
Nothing, that's what. The constraint "implements interface I<T> for any T" is simply not a useful constraint in C#, so there is no way to express it.
It sounds like you have an "XY" problem. That is a problem where you have a bad solution in mind, and now you are asking questions about your bad solution. Ask us a question about the real problem you have, not the bad idea you've got for its solution. What's the real problem?
UPDATE: With the new information in the question it is now much more clear. The feature you want is called generic interface covariance, which was my favourite feature for C# 4.
If you update your interface definition to
interface ISyncInterface<out T> { ... }
then you can use an ISyncInterface<String> in a context where an ISyncInterface<Object> is expected. For example, you could put an ISyncInterface<Giraffe> into a List<ISyncInterface<Animal>> or whatever.
However you are required to ensure that your interface definition only uses T in a covariantly valid position. Your interface is valid as stated, but if for example you ever want to add a method void M(T t); to your interface, it will no longer be covariantly valid. The "out" is a mnemonic telling you that T can only be used as output of methods. Since IEnumerable<T> is also covariantly valid, it's fine; there are no inputs of T in an IEnumerable<T>.
Also, variance only works with generic interfaces and delegates, and the varying types must be reference types. You can't put an ISyncInterface<int> into a List<ISyncInterface<Object>> because int is not a reference type.
There are many posts on SO about covariance and contravariance; you should also read the Microsoft documentation. It can be a confusing feature. If you're interested in the historical details of how we designed and implemented the feature, see my blog.
Perhaps you can try something like this:
public interface MyInterface
{//methods common to all types
void FirstMethod();
}
public interface MyInterface<T> : MyInterface
{//methods specific to a type
void FirstMethod(T parameter);
}
public class MyClassThatHandlesAllInterfaces
{
private List<MyInterface> _allInterfacesT; //first interface in the chain
public void AddInterface<T>(MyInterface<T> ifToAdd)
{
_allInterfacesT.Add(ifToAdd); // <- this is what I'd like to do
}
}
I use this pattern quite often. Because I do not know all the details about your scenario it might not be suitable for you.
But it might help other people searching google.
I'm starting to see this pattern appear often in my code:
class Foo { }
interface IBar
{
Foo Foo { get; }
}
class Bar<TFoo> : IBar where TFoo : Foo
{
public TFoo Foo { get; private set; }
Foo IBar.Foo
{
get
{
return Foo;
}
}
}
Some of its benefits are:
An easy way to check whether an object is of the wrapping type (if (something is IBar))
Strong-typed access to TFoo in closed-constructed Bar<>s
Polymorphic access to Foo in interfaced IBars
One could argue that this kind of pattern is everywhere in the framework (e.g. List<T> : IList), but I wonder if this is just a remnant of .NET 1.0, when generics didn't exist.
Off the top of my head, my main concern is that IBar is not necessarily a proper contract that defines what members a "bar" should provide; it's only a hack to access generically typed members.
Also, if I start adding interfaces for that purpose, I quickly end up with hard to maintain parallel inheritance hierarchies.
Should I be worried about spreading this pattern in my code base? If so, what alternative patterns would provide some or all of the 3 benefits listed above?
Because explicitly implementing abstract members is not allowed, this "ideal" solution is not possible:
class Foo { }
class Bar
{
public abstract Foo Foo { get; }
}
class Bar<TFoo> : Bar where TFoo : Foo
{
private TFoo foo;
Foo Bar.Foo
{
get
{
return foo;
}
}
public new TFoo Foo
{
get
{
return foo;
}
}
}
For me, the summary is you shouldn't think that you implement interfaces just for the sake of augmenting a generic type parameter with more typing.
AFAIK, you use interfaces to provide which are the contracts to work with a given API. Generics are just a language feature/tool to provide more typing where you would end up doing a lot of casts. Hereby, with generics you limit your API to expect arguments implementing one or more interfaces and also with some requirements using generic constraints.
For example, if you just want to accept implementations of given interface called IWhatever, would you use generics?
public void DoStuff<T>(T whatever)
where T : IWhatever
{
}
// versus
public void DoStuff(IWhatever whatever)
{
}
BTW, without generics, how you would check that an implementation to IWhatever is a class and has a public constructor? You would end up with reflection and you're code would smell compared to using generics:
public void DoStuff<T>()
where T : class, IWhatever, new()
{
}
In fact, a generic parameter can constraint that T must inherit a given class and implement one or more interfaces:
public void DoStuff<T>(T arg)
where T : A, IEquatable<T>, IWhatever, IWhichever, IWherever
{
}
And whether if T inherits a type with or without generic parameters or implements interfaces with or without generic parameters, it's not a good or bad design per se but, again, just a language tool that's suitable to specific cases.
Therefore, your statement...
Off the top of my head, my main concern is that IBar is not
necessarily a proper contract that defines what members a "bar" should
provide; it's only a hack to access generically typed members.
...describes a particular design flaw instead of an actual problem with typing generics using the wonders of interfaces.
Conclusion: if IBar isn't a proper contract, then you should revisit your architecture and re-think your solution.
More background on the topic
Actually I thought that my original answer implied that I found the whole solution has a design flaw.
In summary, you're using interfaces to expose an association on certain classes which provide the type of the whole association using a generic type parameter. And you argue that you do this to be able to access such association in a less typed context:
However, I sometime need a "less" typesafe context, hence my question.
And then it's when covariance enters in action! See the following code sample:
public class SuperClass
{
}
public interface IWhatever<out TAssociation>
where TAssociation : SuperClass
{
TAssociation Association { get; }
}
public class SomeImplementation<TAssociation> : IWhatever<TAssociation>
where TAssociation : SuperClass
{
public TAssociation Association { get; set; }
}
Now let's define a derived class of SuperClass:
public class DerivedClass : SuperClass
{
}
And see how this works like a charm:
SomeImplementation<DerivedClass> someImpl = new SomeImplementation<DerivedClass>();
// Covariance: you decide the degree of specialization of TAssociation
// interfaces' type parameter. In our case, we'll upcast TAssociation to
// the SuperClass type.
IWhatever<SuperClass> whatever = someImpl;
Clearly this is the way to go since C# 4.0.
I would say that the right way of expressing your requirement is you need a less specialized context instead of a less typed context. Covariance/contravariance is one of the most powerful features available in C# to cover this scenario when generics are involved in the equation.
This practice isn't a code smell per se. In my case, I go for it when I really need to access one or more associations somewhere where I just need to access certain members with a concrete purpose.
For example, if I'm building a tree-style hierarchy, I would define an interface like this:
public interface IHasParent<out TParent>
{
TParent Parent { get; }
}
Which enables me to do this:
IHasParent<object> withParent = someObject as IHasParent<object>;
if(withParent != null)
{
// Do stuff here if some given object has a parent object
}
But I don't create interfaces indiscriminately because some day I'll need less typed access to some properties. There should be a well defined purpose. Otherwise, you can end up turning a nice solution into a code smell.
You would say don't repeat yourself but I still feel that there's no definitive answer without analyzing your project code base and checking how you really use this kind of interfaces to solve concrete problems.
So, strictly talking, if you use the whole pattern when it's really required, it should be a good design decision.
Maybe you want to avoid the unavoidable
Based on some chat we've had both the OP and me, I feel that the best conclusion is that the OP wants to avoid the unaviodable.
In an object-oriented language like C# interfaces are the right tool to both define type contracts and expose a subset of a full type implementing some interface.
Also, the OP would love a feature in C# like protocols where a class that implicitly fullfils an interface is enough to consider that it implements the interface which would save up many code lines if C# could have this feature:
public interface IWhatever
{
void DoStuff();
}
public class X
{
void DoStuff();
}
public class Y
{
public void HandleStuff(IWhatever whateverImpls)
{
}
}
Y y = new Y();
// Protocols would support passing an instance of X which may not implement
// IWhatever but it implicitly fulfills IWhatever:
y.HandleStuff(new X());
BTW, C# lacks this feature. Therefore, it's a waste of time scratching your head thinking how sweet would be having such feature. You need to deal with what C# has to offer already.
Anyway, if you just need to expose some associations across your object graph and get them selectively, you can use the wonders of interfaces using a more simplified approach than yours. Did you know that you can explicitly implement the same interface more than once if its generic arguments vary?
Why don't you design an interface like this:
public interface IHasAssociation<out TAssociation>
{
TAssociation Association
{
get;
}
}
public interface IHasManyAssociation<out TEnumerable, out TAssociation>
where TEnumerable : IEnumerable<TAssociation>
where TAssociation : Entity
{
TEnumerable Association
{
get;
}
}
public class Entity
{
}
public class Company : Entity
{
}
public class CustomerProfile : Entity
{
}
public class Contact : Entity
{
}
public class Customer :
IHasAssociation<Company>,
IHasAssociation<CustomerProfile>,
IHasManyAssociation<IList<Contact>, Contact>
{
public Company Company
{
get;
set;
}
public CustomerProfile Profile
{
get;
set;
}
public IList<Contact> Contacts
{
get;
set;
}
Company IHasAssociation<Company>.Association => Company;
CustomerProfile IHasAssociation<CustomerProfile>.Association => Profile;
IList<Contact> IHasManyAssociation<IList<Contact>, Contact>.Association => Contacts;
}
Definitively this keep things simpler (KISS!) because you don't need a parallel interface object graph definition, you simply define an interface to being able to get an association of a given type:
var customer = new Customer();
customer.Profile = new CustomerProfile();
customer.Company = new Company();
customer.Contacts = new List<Contact>();
var withCompany = customer as IHasAssociation<Company>;
var withCustomerProfile = customer as IHasAssociation<CustomerProfile>;
var withContacts = customer as IHasManyAssociation<IList<Contact>, Contact>;
if (withCompany != null)
{
Company company = withCompany.Association;
Console.WriteLine("This object has an associated company!");
}
if (withCustomerProfile != null)
{
CustomerProfile profile = withCustomerProfile.Association;
Console.WriteLine("This object has a profile!");
}
if (withContacts != null)
{
IList<Contact> contacts = withContacts.Association;
Console.WriteLine("This object has contacts!");
}
Also, see covariance in action:
if(customer is IHasManyAssociation<IEnumerable<Contact>, Contact>)
{
Console.WriteLine("This object has an enumerable of contacts!");
}
Or here's how you would get all association values of an implementor of one or many IHasAssociation<out TAssociation> interface implementations:
var entityAssociations = typeof(Customer)
.GetInterfaces()
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHasAssociation<>))
.Select(i => i.GetProperty("Association").GetValue(customer));
foreach(var entityAssociation in entityAssociations)
{
Console.WriteLine($"{entityAssociation.GetType().FullName}");
}
This is the real beauty of generic programming! And remember: you won't need to implement IHasAssociation<out TAssociation>/IHasManyAssociation<out TEnumerable, out TAssociation> indiscriminately. That is, you implement on the classes to which associations need to be extracted in some place where you don't care who's the concrete owner of the association and you just need the association itself.
In your question, you express the need for a "generic" wrapper type (note I use the term "generic" here independently of any language).
Well, I don't see any problem with that. And if you ask me how to do it with .NET, I would just design this, once for all types, going one step further from you:
interface IWrapper<T>
{
T BaseObject { get; }
}
Then, a wrapper class would simply be:
class Bar<TFoo> : IWrapper<TFoo> where TFoo : Foo
{
public TFoo BaseObject { get; private set; }
}
I could go further again and define the non generic one, because it's ofen desirable to have both, as it's sometimes hard to work with generic-only clases/interface with meta/reflection code (but this is really optional):
interface IWrapper
{
object BaseObject { get; }
}
If you do this, it could be natural to have IWrapper<T> derive from IWrapper, like this:
interface IWrapper<T> : IWrapper
{
new T BaseObject { get; }
}
And the class would be this:
class Bar<TFoo> : IWrapper<TFoo> where TFoo : Foo
{
public TFoo BaseObject { get; private set; }
object IWrapper.BaseObject => BaseObject;
}
PS: as a side note, you can have a look at WCF's ServiceModel ChannelFactory<T> class that has a combined generic/non generic hierarchy somewhat relevant with your question.
I've found myself in a similar place after developing an API.
I have some questions for you and no answers.
But once you can answer those questions, maybe you know a bit more about how to address this situation.
I wonder how many classes implement IBar.
Are there enough to justify it?
Is this an API and you expose it to client code?
In how many code points do you leverage the polymorphism of the interface?
Just maybe... those answers can make you question the interface's usefulness.
How many times does this structure emerge?
And are you sure it actually does?
I mean, you say you did this:
implement lots of code (A);
refactor it in one place to clean it up;
implement more code (B);
refactor it to clean it up;
notice that B looks similar to A;
implement more code (C);
refactor it to clean it up;
notice that C looks similar to B (by transitivity also to A);
repeat...
Did the structure REALLY emerge, or is it your thinking that mold the code always in the same way?
Which comes first?
the emergence;
the thinking.
This "rinse" and "repeat" approach may be good to start, but just maybe... you've grown out of this methodology and should approach another one:
First design, then implement.
Is this your case? Have you grown that much, that you can finally approach design before implementation?
There's a saying that may apply here:
When you have a hammer, everything looks like a nail.
But let's assume this is not your case.
You don't fall into thought cycles and the underlying problem REALLY has this structure, thus your code reflects the problem's structure.
If you really came up with the same thing multiple times, but it's the problem, not your mind playing tricks, then the following may be a good advice.
Stop coding for a day, and think about it away from keyboard.
Which parts are the same, which different?
Can't you implement this in an even MORE abstract way (actual pattern) into which you inject the specialized code?
Maybe, underlying it all, is a something as simple as a composite pattern, and you could just implement that once and for all, and then reuse it all over the place.
What happened to me was similar, and I ended up with a dependency injection, an abstract factory, an abstract implementation of the composite pattern and an information expert, which took a configuration file and assembled the final object graphs I needed.
It was an excellent, humbling lesson in patterns and architecture, but I regretted actually using it.
Writing the documentation was near impossible and futile.
The code became extremely difficult to follow.
I always had to look things up and rethink about how to use it correctly.
The end result was not that astonishing.
So, if you want to learn and exercise, don't ever stop!
But if you want to just get it done and move on, don't overthink it.
Simple is better!
You may be in a place where you try to perfect your code but actually don't need it.
You're not writing a new API for M$, are you?
Just take this advice:
In a year or two, you won't be able to understand your own code. You must document it, if you make it that complex. If you can't document it, you'll never reuse it. So you don't need this perfection, it will be throw-away code.
In other words:
The real value is not the code, but the documentation that accompanies it. Without documentation there will be no reuse..
In retrospect, I've learned that the correct term for what I want is return type covariance, which is unfortunately not supported in C#, because the language design team does not consider the benefits of implementing the feature outweigh the cost, even though it preserves type safety. (A proposal has been drafted and completed, but it seems to be abandoned).
With return type covariance, the example code could be written as:
class Foo { }
class Bar
{
public virtual Foo Foo { get; }
}
class Bar<TFoo> : Bar where TFoo : Foo
{
public override TFoo Foo { get; }
}
The workaround proposed by Eric Lippert in that linked question is:
class Foo { }
abstract class Bar
{
protected abstract Foo foo { get; }
public Foo Foo => foo;
}
class Bar<TFoo> : Bar where TFoo : Foo
{
protected override Foo foo => this.Foo;
public new TFoo Foo { get { ... } }
}
It has the downside of duplicating not the inheritance hierarchy, but every covariant-simulated property per level of inheritance!
For further reading on how much clutter simulating covariant return types can bring to your code, consider that implementing ICloneable properly implies adding another virtual method per level of inheritance. I'll leave this as my humble plea for that language feature.
The following code shows what I would like to do; that is, I would like to constrain anObject, so that it can be used as a parameter to various methods with use IInterfaceOne or IInterfaceTwo, where neither inherits from the other.
public interface IInterfaceOne { }
public interface IInterfaceTwo { }
public class Implementation : IInterfaceOne, IInterfaceTwo
{
}
public interface IInterfaceOneAndTwo : IInterfaceOne, IInterfaceTwo { }
public class UsingImplementation
{
IInterfaceOneAndTwo anObject = (IInterfaceOneAndTwo)(new Implementation()); //fails because Implementation doesnt acctually implement IInterfaceOneAndTwo
}
This example fails however as IInterfaceOneAndTwo is an interface in its own right, and Implementation does not implement it.
I know if I used generics I could constrain them, but I am wondering, if there is a way to do this without generics?
Is there a way to say anObject shall implement IInterfaceOne and IInterfaceTwo, without using IInterfaceOneAndTwo?
Not the way you have it currently. Only generic constraints have that ability.
You could rewrite it to use generics:
public class UsingImplementation<T>
where T : IInterface1, IInterface2, new()
{
T anObject = new T();
void SomeMethod() {
anObject.MethodFromInterface1();
}
}
You can also have generic methods, not only generic classes
public void DoSomething<T>(T value)
where T : IInterface1, IInterface2
{
value.DoInterface1Things();
value.DoInterface2Things();
}
Or
public void DoSomething<T>()
where T : IInterface1, IInterface2, new()
{
T anObject = new T();
}
You can't do that in C# without generics but there is an alternative workaround to solve the problem without generics that was not mentioned here and might fit for you. This style is often used together with the IoC principle. You could inject the same object twice. Let me change your sample quite a bit...
public interface IInterfaceOne { void Hello(); }
public interface IInterfaceTwo { void World(); }
public class Implementation : IInterfaceOne, IInterfaceTwo
{
public void Hello() { };
public void World() { };
}
public class UsingImplementation
{
private readonly IInterfaceOne one;
private readonly IInterfaceTwo two;
public UsingImplentation(IInterfaceOne one, IInterfaceTwo two)
{
this.one = one;
this.two = two;
}
// do the stuff you want to do with an IInterfaceOne using field one
public DoSomeThingWithOne() { one.Hello(); }
// do the stuff you want to do with an IInterfaceTwo using field two
public DoSomeThingWithTwo() { two.World(); }
}
Then you could wire up the things this way:
var oneAndTwo = new Implementation();
var a = new UsingImplementation(oneAndTwo, oneAndTwo);
// operates on the first param (which is the same as the second)
a.DoSomeThingWithOne();
// operates on the second param (which is the same as the first)
a.DoSomeThingWithTwo();
Have a look for IoC principle (Inversion of Control) and Dependency Injection and you'll find more solutions similiar to this one.
This way you don't need to create an extra Interface combining InterfaceOne and InterfaceTwo, two.
"Incoming" generic class parameters and generic method parameters can combine types, but there is no facility for variables or fields to represent "composite" types. Further, in order to pass an object to a parameter of a generic type which combines multiple constraints, the object must be cast to a type which in fact implements all of those constraints. This can be difficult.
For example, suppose class Foo and Bar both implement Intf1 and Intf2. One wishes to write a function AddToList<T>(thing as T) where T:Intf1,Intf2. Such a function will perfectly happily accept objects of type Foo or Bar. Suppose, however, one wishes to use such a function to add all objects to the same list (which might be a mix of Foo, Bar, and any number of other types that also happen to implement Intf1 and Intf2) and then later pass those objects to a function whose parameter is likewise constrained to implement both Intf1 and Intf2. One could cast to Foo any object which happened to be a Foo, and cast to Bar any object which happened to be a Bar, but if other types are written which also handle Intf1 and Intf2, it would be difficult to deal with them.
It is possible to solve the problem, somewhat awkwardly, without using Reflection or other such tricks. Define an interface IActUpon<Base1, Base2> with a method ActUpon<thingType>ActUpon(thingType thing) where thingType: Base1, Base2. Implementations of such a method will be able to pass parameter thing to other methods requiring generic method parameter constrained to Base1 and Base2. The biggest difficulties with such an approach are that one must write separate code for each possible number of constraints, and that in many places where one would have used a lambda expression one will instead have to write an implementation of IActUpon....
If this is desirable then there has to be a logical connection between IInterfaceOne and IInterfaceTwo and the implementing class should implement the combined interface:
class Implementation : IInterfaceOneAndTwo { ... }
If this is not possible, because it's not (all) your code then you may have to rethink the UsingImplementation. It simply doesn't fit the available surface.
We define interface as below:
interface IMyInterface
{
void MethodToImplement();
}
And impliments as below:
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
}
instead of creating a interface , why can we use the function directly like below :-)
class InterfaceImplementer
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
}
Any thoughts?
You are not implementing the interface in the bottom example, you are simply creating an object of InterfaceImplementer
EDIT: In this example an interface is not needed. However, they are extremely useful when trying to write loosely coupled code where you don't have to depend on concrete objects. They are also used to define contracts where anything implementing them has to also implement each method that it defines.
There is lots of information out there, here is just a brief intro http://www.csharp-station.com/Tutorials/Lesson13.aspx
If you really want to understand more about interfaces and how they can help to write good code, I would recommend the Head First Design Patterns book. Amazon Link
instead of creating a interface , why
can we use the function directly like
below
Are you asking what the point of the interface is?
Creating an interface allows you to decouple your program from a specific class, and instead code against an abstraction.
When your class is coded against an interface, classes that use your class can inject whichever class they want that implements this interface. This facilitates unit testing since not-easily-testable modules can be substituted with mocks and stubs.
The purpose of the interface is for some other class to be able to use the type without knowing the specific implementation, so long as that type conforms to a set of methods and properties defined in the interface contract.
public class SomeOtherClass
{
public void DoSomething(IMyInterface something)
{
something.MethodToImplement();
}
}
public class Program
{
public static void Main(string[] args)
{
if(args != null)
new SomeOtherClass().DoSomething(new ImplementationOne());
else
new SomeOtherClass().DoSomething(new ImplementationTwo());
}
}
Your example doesn't really follow that pattern, however; if one that one class implements the interface, then there really isn't much of a point. You can call it either way; it just depends on what kind of object hierarchy you have and what you intend to do for us to say whether using an interface is a good choice or not.
To sum: Both snippets you provide are valid code options. We'd need context to determine which is a 'better' solution.
Interfaces are not required, there is nothing wrong with the last section of code you posted. It is simply a class and you call one of it's public methods. It has no knowledge that an interface exists that this class happens to satisfy.
However, there are advantages:
Multiple Inheritance - A class can only extend one parent class, but can implement any number of interfaces.
Freedom of class use - If your code is written so that it only cares that it has an instance of SomethingI, you are not tied to a specific Something class. If tomorrow you decide that your method should return a class that works differently, it can return SomethingA and any calling code will not need to be changed.
The purpose of interfaces isn't found in instantiating objects, but in referencing them. Consider if your example is changed to this:
static void Main()
{
IMyInterface iImp = new InterfaceImplementer();
iImp.MethodToImplement();
}
Now the iTmp object is of the type IMyInterface. Its specific implementation is InterfaceImplementer, but there may be times where the implementation is unimportant (or unwanted). Consider something like this:
interface IVehicle
{
void MoveForward();
}
class Car : IVehicle
{
public void MoveForward()
{
ApplyGasPedal();
}
private void ApplyGasPedal()
{
// some stuff
}
}
class Bike : IVehicle
{
public void MoveForward()
{
CrankPedals();
}
private void CrankPedals()
{
// some stuff
}
}
Now say you have a method like this somewhere:
void DoSomething(IVehicle)
{
IVehicle.MoveForward();
}
The purpose of the interface becomes more clear here. You can pass any implementation of IVehicle to that method. The implementation doesn't matter, only that it can be referenced by the interface. Otherwise, you'd need a DoSomething() method for each possible implementation, which can get messy fast.
Interfaces make it possible for an object to work with a variety of objects that have no common base type but have certain common abilities. If a number of classes implement IDoSomething, a method can accept a parameter of type IDoSomething, and an object of any of those classes can be passed to it. The method can then use all of the methods and properties applicable to an IDoSomething without having to worry about the actual underlying type of the object.
The point of the interface is to define a contract that your implementing class abides by.
This allows you to program to a specification rather than an implementation.
Imagine we have the following:
public class Dog
{
public string Speak()
{
return "woof!";
}
}
And want to see what he says:
public string MakeSomeNoise(Dog dog)
{
return dog.Speak();
}
We really don't benefit from the Interface, however if we also wanted to be able to see what kind of noise a Cat makes, we would need another MakeSomeNoise() overload that could accept a Cat, however with an interface we can have the following:
public interface IAnimal
{
public string Speak();
}
public class Dog : IAnimal
{
public string Speak()
{
return "woof!";
}
}
public class Cat : IAnimal
{
public string Speak()
{
return "meow!";
}
}
And run them both through:
public string MakeSomeNoise(IAnimal animal)
{
return animal.Speak();
}