Polymorphic or generic approach is better? C# - c#

I have two classes and an interface like
interface IVehicle
{
void Drive();
}
class Benz :IVehicle
{
public void Drive()
{
Console.WriteLine("WOW! driving benz");
}
}
class Ferrari : IVehicle
{
public void Drive()
{
Console.WriteLine("WOW! driving ferrari");
}
}
I got a Driver class which uses this.
class Driver
{
public void StartDriving(IVehicle vehicle)
{
vehicle.Drive();
}
}
There is one more driver which is generic.
class GenericDriver
{
public void StartDriving<T>() where T : IVehicle , new()
{
T vehicle = new T();
vehicle.Drive();
}
}
Questions
Do you see any advantages for the generic implementation compared to normal Driver? If yes, what are they?
Which one do you prefer? A generic one or the normal one?
Is there a better way to implement a generic driver?
I am getting a feeling that generics in C# is very limited when compared with C++ templates. Is that true?
Any thoughts?

Absolutely no advantages in this case whatsoever. Except if you really want to create an instance of T in Drive(), which can be done without generics with delegate IVehicle VehicleBuilder();
It depends on the situation. But generally speaking I'd prefer first.
Again: it depends on what you want to do.
Yes, this is true. Remember though, that C++ templates are compile-time (JIT time) constructs, whereas C# generics are run-time constructs.
Now on why would I want a generic Driver. Consider:
class Driver<TVehicle>
where TVehicle : class, IVehicle, new()
{
public TVehicle Vehicle { get; set }
public Driver()
{
Vehicle = new TVehicle();
}
}
This way I'll be able to use a strongly-typed Driver<>.Vehicle property which will be of a particular type, rather than of a more common IVehicle.

I don't really see any advantages in your example, but they do different things. The normal one has the ability to use an already created vehicle, while the generic one can only create a new one.
Since these methods do different things, it depends. Whichever works better for your code. Personally I would use the normal one.
I'm not really sure why you even want to use generics. It doesn't help you much in this case.
Yes, C++ templates are much more powerful. Just look at all the weird Boost libraries. This is mainly because C++ templates are done at compile time, not run time/JIT time like in .NET.

The second means you need to construct a new object every time it is called, whereas the first would allow you to construct outside of the call and hence reuse the object, which could save a lot on resources if called often.

Related

Why do I need an explicit interface declaration here? (C#) [duplicate]

The use case is some what like this:
public class SomeClass : ICloneable
{
// Some Code
// Implementing interface method
public object Clone()
{
// Some Clonning Code
}
}
Now my question is Why is it not possible to use "SomeClass(As it is derived from object)" as a return type of Clone() method if we consider the Funda's of Covariance and Contravariance?
Can somebody explain me the reason behind this implementation of Microsoft ????
Let me rephrase the question:
Languages such as C++ allow an overriding method to have a more specific return type than the overridden method. For example, if we have types
abstract class Enclosure {}
class Aquarium : Enclosure {}
abstract class Animal
{
public virtual Enclosure GetEnclosure();
}
then this is not legal in C# but the equivalent code would be legal in C++:
class Fish : Animal
{
public override Aquarium GetEnclosure() { ...
What is this feature of C++ called?
The feature is called "return type covariance". (As another answer points out, it would also be possible to support "formal parameter type contravariance", though C++ does not.)
Why is it not supported in C#?
As I've pointed out many times, we don't have to provide a reason why a feature is not supported; the default state of all features is "not supported". It's only when huge amounts of time and effort are put into making an implementation that a feature becomes supported. Rather, features that are implemented must have reasons for them, and darn good reasons at that considering how much it costs to make them.
That said, there are two big "points against" this feature that are the primary things preventing it from getting done.
The CLR does not support it. In order to make this work we'd basically have to implement the exactly matching method and then make a helper method that calls it. It's doable but it gets to be messy.
Anders thinks it is not a very good language feature. Anders is the Chief Architect and if he thinks it is a bad feature, odds are good its not going to get done. (Now, mind you, we thought that named and optional parameters was not worth the cost either, but that did eventually get done. Sometimes it becomes clear that you do have to grit your teeth and implement a feature that you don't really like the aesthetics of in order to satisfy a real-world demand.)
In short, there are certainly times when it would be useful, and this is a frequently requested feature. However, it's unlikely that we're going to do it. The benefit of the feature does not pay for its costs; it considerably complicates the semantic analysis of methods, and we have no really easy way to implement it.
A non-broken implementation of interface-implementation variance would have to be covariant in the return type and contravariant in the argument types.
For example:
public interface IFoo
{
object Flurp(Array array);
}
public class GoodFoo : IFoo
{
public int Flurp(Array array) { ... }
}
public class NiceFoo : IFoo
{
public object Flurp(IEnumerable enumerable) { ... }
}
Both are legal under the "new" rules, right? But what about this:
public class QuestionableFoo : IFoo
{
public double Flurp(Array array) { ... }
public object Flurp(IEnumerable enumerable) { ... }
}
Kind of hard to tell which implicit implementation is better here. The first one is an exact match for the argument type, but not the return type. The second is an exact match for the return type, but not the argument type. I'm leaning toward the first, because whoever uses the IFoo interface can only ever give it an Array, but it's still not entirely clear.
And this isn't the worst, by far. What if we do this instead:
public class EvilFoo : IFoo
{
public object Flurp(ICollection collection) { ... }
public object Flurp(ICloneable cloneable) { ... }
}
Which one wins the prize? It's a perfectly valid overload, but ICollection and ICloneable have nothing to do with each other and Array implements both of them. I can't see an obvious solution here.
It only gets worse if we start adding overloads to the interface itself:
public interface ISuck
{
Stream Munge(ArrayList list);
Stream Munge(Hashtable ht);
string Munge(NameValueCollection nvc);
object Munge(IEnumerable enumerable);
}
public class HateHateHate : ISuck
{
public FileStream Munge(ICollection collection);
public NetworkStream Munge(IEnumerable enumerable);
public MemoryStream Munge(Hashtable ht);
public Stream Munge(ICloneable cloneable);
public object Munge(object o);
public Stream Munge(IDictionary dic);
}
Good luck trying to unravel this mystery without going insane.
Of course, all of this is moot if you assert that interface implementations should only support return-type variance and not argument-type variance. But almost everyone would consider such a half-implementation to be completely broken and start spamming bug reports, so I don't think that the C# team is going to do it.
I don't know if this is the official reason why it's not supported in C# today, but it should serve as a good example of the kind of "write-only" code that it could lead to, and part of the C# team's design philosophy is to try to prevent developers from writing awful code.
You have to implement an interface's methods exactly as they are in the interface. ICloneable's Clone method returns an object, so your SomeClass must also return an object. You can, however, return a SomeClass instance in SomeClass's Clone method without any problem, but the method definition must match the interface:
public class SomeClass: IClonable
{
// Some Code
//Implementing interface method
Public object Clone()
{
SomeClass ret = new SomeClass();
// copy date from this instance to ret
return ret;
}
}
In terms of explaining the reasons behind C# decisions, Eric Lippert from Microsoft has written much explaining Contra/CoVariance in C#... here's the tag list from his blog:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
[Edit]
Specific to your question, this might be the right post.. http://blogs.msdn.com/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx
It looks like the kind of thing they could have used generics for, but it seems there is a good reason why they did not.
It is talked about here:
http://bytes.com/topic/c-sharp/answers/469671-generic-icloneable
Basically, a generic interface that would allow:
public class MyClass : IClonable<MyClass>
would also allow:
public class MyClass : IClonable<MyOtherClass>
which doesn’t really provide any benefit, and might confuse things.
According to the C# specification, you must use a method with an identical signature when overriding or implementing an interface method. Keep in mind that Microsoft does not own C#. Their C# compiler is simply their implementation of it. So why would the spec do things this way? I can only guess, but I suspect it was for ease of implementation.

C# Strategy pattern design problem

I'm having troubles trying to design classes.
I have abstract Chip class, STM8 class which extends Chip and implements IConfigurable (which has Configure method).
I expect each class, which implements IConfigurable to have a method Configure, which takes one arguments to decide what to configure, using strategy pattern (methods).
Psuedo code:
public void Configure(Periphial p)
{
this.periphials[p]();
}
Of course things to configure differ on each class. For example, STM8 can have GPIO and Timers, and STM8L can only have GPIO. Then, the way each subclass is created should be stupid-proof so I would like to force people to declare their own enum inside their classes.
At last, would it be a good idea to initialize a dictionary with a pair of enum/delegate for showing what is possible to configure? this.periphials used in pseudo-code above?
And what if your Periphial (should it be named Peripheral instead?) did have a Configure method?
foreach (Peripheral p in peripherals) {
p.Configure();
}
or if your Peripheral returned a configurator?
foreach (Peripheral p in peripherals) {
IConfigurator configurator = p.GetConfigurator();
configurator.Configure();
}
Try working with generics if you dont have too much peripherials.
So make a type for every peripherial TPeripherial1, TPeripherial2, etc.
Then make a generic interface
interface IConfigurable<T> : where T TPeripherialBase
{
void Configure<T>()
}
Then implement as much typed configurable interfaces on you class as it supports.
These all methods can be routed to one private method which will not be type and idiot safe.
I don't think you can do what you suggest with the enum for the possible peripherals.
What I think you should do is check the type of the provided Peripheral which is provided to the Configure() and return a custom exception of if the type is not supporter.
So for STM8L, you would do:
public void Configure(Peripheral p)
{
if (p is GPIO) ConfigureGPIO()
else throw new NotAvailablePeripheralException(p);
}
If you were able to have some enumeration available for the subclasses of Chip, it would be exactly the same as if you could define Porperties such as myChip.GPIO. Using class inheritage hides what the object really is at compile time...

Why the concept of "Covariance" and "Contravariance" are applicable while implementing the methods of an interface?

The use case is some what like this:
public class SomeClass : ICloneable
{
// Some Code
// Implementing interface method
public object Clone()
{
// Some Clonning Code
}
}
Now my question is Why is it not possible to use "SomeClass(As it is derived from object)" as a return type of Clone() method if we consider the Funda's of Covariance and Contravariance?
Can somebody explain me the reason behind this implementation of Microsoft ????
Let me rephrase the question:
Languages such as C++ allow an overriding method to have a more specific return type than the overridden method. For example, if we have types
abstract class Enclosure {}
class Aquarium : Enclosure {}
abstract class Animal
{
public virtual Enclosure GetEnclosure();
}
then this is not legal in C# but the equivalent code would be legal in C++:
class Fish : Animal
{
public override Aquarium GetEnclosure() { ...
What is this feature of C++ called?
The feature is called "return type covariance". (As another answer points out, it would also be possible to support "formal parameter type contravariance", though C++ does not.)
Why is it not supported in C#?
As I've pointed out many times, we don't have to provide a reason why a feature is not supported; the default state of all features is "not supported". It's only when huge amounts of time and effort are put into making an implementation that a feature becomes supported. Rather, features that are implemented must have reasons for them, and darn good reasons at that considering how much it costs to make them.
That said, there are two big "points against" this feature that are the primary things preventing it from getting done.
The CLR does not support it. In order to make this work we'd basically have to implement the exactly matching method and then make a helper method that calls it. It's doable but it gets to be messy.
Anders thinks it is not a very good language feature. Anders is the Chief Architect and if he thinks it is a bad feature, odds are good its not going to get done. (Now, mind you, we thought that named and optional parameters was not worth the cost either, but that did eventually get done. Sometimes it becomes clear that you do have to grit your teeth and implement a feature that you don't really like the aesthetics of in order to satisfy a real-world demand.)
In short, there are certainly times when it would be useful, and this is a frequently requested feature. However, it's unlikely that we're going to do it. The benefit of the feature does not pay for its costs; it considerably complicates the semantic analysis of methods, and we have no really easy way to implement it.
A non-broken implementation of interface-implementation variance would have to be covariant in the return type and contravariant in the argument types.
For example:
public interface IFoo
{
object Flurp(Array array);
}
public class GoodFoo : IFoo
{
public int Flurp(Array array) { ... }
}
public class NiceFoo : IFoo
{
public object Flurp(IEnumerable enumerable) { ... }
}
Both are legal under the "new" rules, right? But what about this:
public class QuestionableFoo : IFoo
{
public double Flurp(Array array) { ... }
public object Flurp(IEnumerable enumerable) { ... }
}
Kind of hard to tell which implicit implementation is better here. The first one is an exact match for the argument type, but not the return type. The second is an exact match for the return type, but not the argument type. I'm leaning toward the first, because whoever uses the IFoo interface can only ever give it an Array, but it's still not entirely clear.
And this isn't the worst, by far. What if we do this instead:
public class EvilFoo : IFoo
{
public object Flurp(ICollection collection) { ... }
public object Flurp(ICloneable cloneable) { ... }
}
Which one wins the prize? It's a perfectly valid overload, but ICollection and ICloneable have nothing to do with each other and Array implements both of them. I can't see an obvious solution here.
It only gets worse if we start adding overloads to the interface itself:
public interface ISuck
{
Stream Munge(ArrayList list);
Stream Munge(Hashtable ht);
string Munge(NameValueCollection nvc);
object Munge(IEnumerable enumerable);
}
public class HateHateHate : ISuck
{
public FileStream Munge(ICollection collection);
public NetworkStream Munge(IEnumerable enumerable);
public MemoryStream Munge(Hashtable ht);
public Stream Munge(ICloneable cloneable);
public object Munge(object o);
public Stream Munge(IDictionary dic);
}
Good luck trying to unravel this mystery without going insane.
Of course, all of this is moot if you assert that interface implementations should only support return-type variance and not argument-type variance. But almost everyone would consider such a half-implementation to be completely broken and start spamming bug reports, so I don't think that the C# team is going to do it.
I don't know if this is the official reason why it's not supported in C# today, but it should serve as a good example of the kind of "write-only" code that it could lead to, and part of the C# team's design philosophy is to try to prevent developers from writing awful code.
You have to implement an interface's methods exactly as they are in the interface. ICloneable's Clone method returns an object, so your SomeClass must also return an object. You can, however, return a SomeClass instance in SomeClass's Clone method without any problem, but the method definition must match the interface:
public class SomeClass: IClonable
{
// Some Code
//Implementing interface method
Public object Clone()
{
SomeClass ret = new SomeClass();
// copy date from this instance to ret
return ret;
}
}
In terms of explaining the reasons behind C# decisions, Eric Lippert from Microsoft has written much explaining Contra/CoVariance in C#... here's the tag list from his blog:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
[Edit]
Specific to your question, this might be the right post.. http://blogs.msdn.com/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx
It looks like the kind of thing they could have used generics for, but it seems there is a good reason why they did not.
It is talked about here:
http://bytes.com/topic/c-sharp/answers/469671-generic-icloneable
Basically, a generic interface that would allow:
public class MyClass : IClonable<MyClass>
would also allow:
public class MyClass : IClonable<MyOtherClass>
which doesn’t really provide any benefit, and might confuse things.
According to the C# specification, you must use a method with an identical signature when overriding or implementing an interface method. Keep in mind that Microsoft does not own C#. Their C# compiler is simply their implementation of it. So why would the spec do things this way? I can only guess, but I suspect it was for ease of implementation.

Design Pattern to Handle Grouping Similar Entities Together

Over the past few years I've been on projects where we've run into a similar problem in our object hierarchy that always seems to cause problems. I was curious if anyone here knew of a classical OOP (Java, C#, PHP5, etc) design pattern that could gracefully handle this situation.
Say we have an existing system. This system has, among other things, two types of entities, each modeled with an individual class. Let's say
Customer
SalesRepresentative
For historical reasons, neither of these classes inherit from the same base class or share a common interface.
The problem I've seen is, inevitably, a new feature gets specced out that requires us to treat the Customer and the SalesRepresentative as the same type of Object. The way I've seen this handled in the past is to create a new class that includes a member variable for both, and then each method will operate on the objects differently depending on which is set
//pseudo PHPish code
class Participator
{
public $customer;
public $salesRepresentative;
public function __construct($object)
{
if(object is instance of Customer)
{
$this->customer = $object;
}
if(object is instance of SalesRepresentative)
{
$this->salesRepresentative = $object;
}
}
public function doesSomething()
{
if($customer)
{
//We're a customer, do customer specific stuff
}
else if($salesRepresentative)
{
//We're a salesRepresentative, do sales
//representative specific stuff
}
}
}
Is there a more graceful way of handling this type of situation?
Maybe a Wrapper can be used here. Create a Wrapper Interface say ParticipatorWrapper that specifies the new functionality and build concrete Wrappers for each class, say CustomerWrapper and SalesRepresentativeWrapper that both implement the new functionality.
Then simply wrap the object in its appropriate wrapper and write code that targets the ParticipatorWrapper.
Update: Javaish code:
interface ParticipatorWrapper{
public void doSomething();
}
class CustomerWrapper implements ParticipatorWrapper{
Customer customer;
public void doSomething(){
//do something with the customer
}
}
class SaleREpresentativeWrapper implements ParticipatorWrapper{
SaleRepresentative salesRepresentative;
public void doSomething(){
//do something with the salesRepresentative
}
}
class ClientOfWrapper{
public void mymethod(){
ParticipatorWrapper p = new ParticipatorWrapper(new Customer());
p.doSomething();
}
}
This is an alternative to that Vincent's answer, taking an opposite sort of approach. As I note below, there are some downsides, but your specific problem may obviate those and I think this solution is simpler in those cases (or you may want to use some combination of this solution and Vincent's).
Rather than wrapping the classes, introduce hooks in the classes and then pass them the functions. This is a reasonable alternative if you're looking to do the same thing with the same data from both classes (which I am guessing you are, based on lamenting that the two classes don't have a shared superclass).
This is using Visitor instead of Wrapper. Javaish this be something like:
public <Output> Output visit(Vistor<Output> v) {
return v.process(...all shared the fields in Customer/SalesRep...);
}
And then you have a Visitor interface which all your functions inherit from that looks like:
interface Visitor<Output> {
public Output process(...shared fields...);
}
There are someways to chop what gets passed to your Visitor, but the involves introducing new classes to specify which inputs to use, which becomes wrapping anyways, so you might as well use Vincent's answer.
The downside to this solution is if you do something that alters the structure of the class fields, you can buy yourself lots of refactoring, which is less of a problem in Vincent's answer. This solution is also a little bit less useful if you're making modifications to the data stored in the Customer/SalesRep instance, as you'd effectively have to wrap those inside the Visitor.
I think you could apply the concept of mixins to your classes to get the functionality you want.

C# - Interface -Help in power of Interface

I am new to C#. Recently I have read an article.It suggests
"One of the practical uses of interface is, when an interface reference is created that can
work on different kinds of objects which implements that interface."
Base on that I tested (I am not sure my understanding is correct)
namespace InterfaceExample
{
public interface IRide
{
void Ride();
}
abstract class Animal
{
private string _classification;
public string Classification
{
set { _classification = value;}
get { return _classification;}
}
public Animal(){}
public Animal(string _classification)
{
this._classification = _classification;
}
}
class Elephant:Animal,IRide
{
public Elephant(){}
public Elephant(string _majorClass):base(_majorClass)
{
}
public void Ride()
{
Console.WriteLine("Elephant can ride 34KPM");
}
}
class Horse:Animal,IRide
{
public Horse(){}
public Horse(string _majorClass):base(_majorClass)
{
}
public void Ride()
{
Console.WriteLine("Horse can ride 110 KPH");
}
}
class Test
{
static void Main()
{
Elephant bully = new Elephant("Vertebrata");
Horse lina = new Horse("Vertebrata");
IRide[] riders = {bully,lina};
foreach(IRide rider in riders)
{
rider.Ride();
}
Console.ReadKey(true);
}
}
}
Questions :
Beyond such extend, what are the different way can we leverage the elegance of Interfaces ?
What is the Key point that I can say this can be only done by interface (apart from
multiple inheritances) ?
(I wish to gather the information from experienced hands).
Edit :
Edited to be concept centric,i guess.
The point is, you could also have a class Bike which implements IRide, without inheriting from Animal. You can think of an interface as being an abstract contract, specifying that objects of this class can do the things specified in the interface.
Because C# doesn't support multiple inheritance (which is a good thing IMHO) interfaces are the way you specify shared behavior or state across otherwise unrelated types.
interface IRideable
{
void Ride();
}
class Elephant : Animal, IRideable{}
class Unicycle: Machine, IRideable{}
In this manner, say you had a program that modeled a circus (where machines and animals had distinct behavior, but some machines and some animals could be ridden) you can create abstract functionality specific to what is means to ride something.
public static void RideThemAll(IEnumerable<IRideable> thingsToRide)
{
foreach(IRideable rideable in thingsToRide)
ridable.Ride();
}
As Lucero points out, you could implement other classes that implement IRide without inherting from Animal and be able to include all of those in your IRide[] array.
The problem is that your IRide interface is still too broad for your example. Obviously, it needs to include the Ride() method, but what does the Eat() method have to do with being able to ride a "thing"?
Interfaces should thought of as a loose contract that guarantees the existance of a member, but not an implementation. They should also not be general enough to span "concepts" (eating and riding are two different concepts).
You are asking the difference between abstract classes and interfaces. There is a really good article on that here.
Another great advantage is lower coupling between software components. Suppose you want to be able to feed any rideable animal. In this case you could write the following method:
public void Feed(IRide rideable)
{
//DO SOMETHING IMPORTANT HERE
//THEN DO SOMETHING SPECIFIC TO AN IRide object
rideable.Eat();
}
The major advantage here is that you can develop and test the Feed method without having any idea of the implementation of IRide passed in to this method. It could be an elephant, horse, or donkey. It doesn't matter. This also opens up your design for using Inversion of Control frameworks like Structure Map or mocking tools like Rhino Mock.
Interfaces can be used for "tagging" concepts or marking classes with specifically functionality such as serializable. This metadata (Introspection or Reflection) can be used with powerful inversion-of-control frameworks such as dependency injection.
This idea is used throughout the .NET framework (such as ISerializable) and third-party DI frameworks.
You already seem to grasp the general meaning of Interfaces.
Interfaces are just a contract saying "I support this!" without saying how the underlying system works.
Contrast this to a base or abstract class, which says "I share these common properties & methods, but have some new ones of my own!"
Of course, a class can implement as many interfaces as it wants, but can only inherit from one base class.

Categories

Resources