I am creating a class library that will be used to create other applications with specific functionality. The library should implement all of the concrete functionality, and the implementing application will add specific business rules to the classes. Typically this is a trivial representation of some objects:
In class library:
interface IWheel
{
int Radius { get; set; }
string Color { get; set; }
}
abstract class Wheel : IWheel
{
int Radius { get; set; }
string Color { get; set; }
}
interface ICar
{
string Color { get; set; }
List<IWheel> Wheels { get; set; }
}
abstract class Car : ICar
{
string Color { get; set; }
List<IWheel> Wheels { get; set; }
public Car()
{
List<IWheel> Wheels = new List<IWheel>();
}
}
In implementing application business logic:
class SpecialWheel : Wheel
{
int SpecialWheelProperty { get; set; }
}
class SpecialCar : Car
{
string SpecialCarProperty { get; set; }
}
In implementing application instantiation:
SpecialWheel wheel1 = new SpecialWheel { SpecialWheelProperty = 6 };
SpecialWheel wheel2 = new SpecialWheel { SpecialWheelProperty = 6 };
SpecialWheel wheel3 = new SpecialWheel { SpecialWheelProperty = 8 };
SpecialWheel wheel4 = new SpecialWheel { SpecialWheelProperty = 8 };
SpecialCar car = new SpecialCar();
car.Wheels.Add(wheel1);
car.Wheels.Add(wheel2);
car.Wheels.Add(wheel3);
car.Wheels.Add(wheel4);
All is good so far, until I try to do something like:
// Cant do this as "SpecialWheelProperty" is not in the Interface contract
int wheelSpecialProperty = car.Wheels.First().SpecialWheelProperty;
I could of course add the "SpecialWheelProperty" to the IWheel Interface and make it an abstract property of the Wheel class, but this would defeat my final objective of implementing the business logic in derived classes.
I have a few ideas floating round in my head (maybe generics), but, in this case what is the best approach, and an example of that approach?
The problem is that your code expresses no relationship between the SpecialCar and SpecialWheel classes, yet expects the interface of SpecialCar to expose SpecialWheel instances. The fact that you're actually adding all SpecialWheel instances is entirely coincidental.
This seems like a task for generics, with the base class accepting a type parameter implementing IWheel.
abstract class Car<TWheel> : ICar where TWheel : IWheel
{
string Color { get; set; }
ICollection<TWheel> Wheels { get; set; }
public Car()
{
Wheels = new List<TWheel>();
}
}
class SpecialCar : Car<SpecialWheel> {
// Whatever
}
Now you can still do this without losing any type safety:
int swp = car.Wheels.First().SpecialWheelProperty;
A word of caution: while this technique makes your desired code possible, it can quickly grow out of control if used in deep class hierarchies. Please use sparingly.
So far as I understand a
SpecialWheel
Is on the business logic so that appears to be normal to cast to get it specific properties:
int wheelSpecialProperty = (car.Wheels.First() as SpecialWheel).SpecialWheelProperty;
A question: why do you create a constructor in
Car
Since it is abstract?
I think, it will be hard to answer this question in one precise way. The problem is to understand your system. Here you only have what I called a "technique". In this case an inheritance and polymorphism. But when you build system, it is usually more than this. You may have a framework, plumbing if you like, where all operations are done on interface level. Factories. Then, in specialized areas, you have business-specific code like this:
class CarFactory
{
public static ICar BuildCar(int kind);
if (int == 0)
return new RegularCar();
else
return new SpecialCar();
}
so in your "Special" code you can add special property value
SpecialCar sc = (SpecialCar)CarFactory.BuildCar(1); // notice casting
sc.SpecialProperty = "special value";
So, only specific clients/consumers will know about special properties. Your application will operate with
ICar, IWheel, // etc
for example, when you acquire regular car, your client has no idea about 1, only 0.
RegularCar rc = (RegularCar)CarFactory.BuildCar(0); // notice casting
But the handler that calls "AddWheels" has no idea of what car it is and declared as
CarBuilderWheelHandler.AddWheels(ICar c, List<IWheel> w)
CarBuilderWheelHandler may need to mount tires, inflate and balance each of them. But your special wheel may have installed Tire pressure monitoring system rather than regular valve. In this case your special car has a device to monitor TPMS and knows how to handle special wheel properties. But when it flows from handler to handler, those handlers don't know the specifics of "special" things. Hadlers work with interfaces.
void AddWheels(ICar c, List<IWheel> w)
{
MountRubber(w);
Inflate(w);
Balance(w);
c.Wheels = w;
}
Then somewhere inside special car, it knows how to monitor pressure
void Timer_Tick(...)
{
foreach(SpecialWheel w in _wheels)
{
if w.Pressure < _pressureSetByDriver //'Pressure' is not part of IWheel
SendPressureWarningToDashboard();
}
}
This is really abstract example, may be only good for you to understand what is purpose of Abstract objects in OOP.
I believe that your question can have many answers and we don't have exact context under which you working
Related
Lets say we have this example hierarchy:
abstract class Shape { }
class Circle : Shape
{
public int Radius { get; set; }
}
class Rectangle : Shape
{
public int A { get; set; }
public int B { get; set; }
}
I am wondering if it's possible to use pattern matching in C# on a variable of type Shape to determine if it has property Radius e.g.
// Imaginary syntax
if (myShape is { int Radius} )
{
}
I have not found that this is possible, so I assume the answer is no, but probably someone knows better.
Alternatives that I can think of:
Enumerate all the known scenarios (i.e. of Type Circle, etc.), downside is that an introduction of a new type in the future will break it
Introducing an interface, which might be cumbersome depending on the scenario
Using reflection (not too nice)
i have an abstract model named BetaModel that inherit its parent AlphaModel. Then
I have a bunch of request models that inherit the BetaModel and therefore naturally inherit AlphaModel, However I have the other bunch of response models which have to inherit the fields of BetaModel and do not need the fields in AlphaModel.
[Note: AlphaModel and BetaModel only contain some plain fields]
What is the elegant way to have the response models inherit the BetModel but ignore the AlphaModel?
Is it OK to turn the AlphaModel becomes an Interface, so that it only implemented in all the request models but not the response models?
So, you are basically contradicting the description with the "desired" architecture.
Also, always bare in mind that you don't decide architecture based on results ("Is it OK to turn the AlphaModel becomes an Interface"): your decisions are based on needs and responsibilities.
Interfaces
Think of that as a contract the classes are agreeing with. They don't hold any implementations and solely describe one contract the class implements
Abstract Classes
They are... Classes. As such, they don't define a contract, they define behaviours. And mostly, when defining an abstract class, you are looking for a abstract behaviour that you want children classes to inherit and/or give meaning to.
Your problem
You are saying some classes must inherit from AlphaModel and some others must NOT inherit from AlphaModel.
Therefore, you are saying that:
A certain class BetaModel1 inherits from AlphaModel and introduces some new members functionality.
Another class BetaModel2 should not expose any member from AlphaModel (which screams it doesn't inherit from AlphaModel) but also introduces the same members/functionality of BetaModel1
In other words, you are saying with all capital letters that BetaModel1 and BetaModel2 DO NOT INHERIT FROM THE SAME CLASS AlphaModel.
Now, back to our initial discussion. C# does not allow multiple inheritance (which looks like what you want to do). But there are strategies either to minimise re-writing code and/or enforce some implementations.
So, the "enforcing of implementation" is basically saying "I want this class to NECESSARILY provide certain functionality". Well... You need an interface for that
C#
public interface IBetaModel
{
string PropertyBeta { get; set; }
string MethodBeta();
}
There is also the AlphaModel
C#
public class AlphaModel
{
public string PropertyAlpha { get; set; }
public string MethodAlpha()
{
return "This is Alpha";
}
}
Now, your desired BetaModel1 (as described above) is quite simply inheriting from AlphaModel and implementing IBetaModel
C#
public class BetaModel1 : AlphaModel, IBetaModel
{
public string PropertyBeta { get; set; }
public string MethodBeta()
{
return "This is Beta?";
}
}
BetaModel2 it's just implementing IBetaModel, in which case:
C#
public class BetaModel2 : IBetaModel
{
public string PropertyBeta { get; set; }
public string MethodBeta()
{
return "This is Beta?";
}
}
The usage of the classes would be like:
C#
public void DoStuffWith(IBetaModel betaModel)
{
betaModel.PropertyBeta = "WOW, it works";
}
public void DoStuff()
{
var betaModel1 = new BetaModel1();
var betaModel2 = new BetaModel2();
AlphaModel betaModel1_ = new BetaModel1();
//AlphaModel betaModel2_ = new BetaModel2(); //won't compile
betaModel1.PropertyAlpha = "Test";
//betaModel2.PropertyAlpha = "Test"; //won't compile
DoStuffWith(betaModel1); //great!!!
DoStuffWith(betaModel2); //great too!!!
}
If this is only about data make every datapart an interface like...
public interface IAlphaModel
{
string SomeField { get; set; }
}
public interface IBetaModel
{
int AnotherField { get; set; }
}
public interface ISomeRequest : IAlphaModel, IBetaModel
{
bool YetAnotherField { get; set; }
}
class SomeRequest : ISomeRequest
{
public string SomeField { get; set; }
public int AnotherField { get; set; }
public bool YetAnotherField { get; set; }
}
public interface IAnotherRequest : IBetaModel
{
long TheUltimateField { get; set; }
}
class AnotherRequest : IAnotherRequest
{
public int AnotherField { get; set; }
public long TheUltimateField { get; set; }
}
Edit
Of course you can have the interfaces have more than one member if they are tied logically together.
I created this interface:
public interface IPhrase
{
int CategoryId { get; set; }
string PhraseId { get; set; }
string English { get; set; }
string Romaji { get; set; }
string Kana { get; set; }
string Kanji { get; set; }
}
and this class:
public class Phrase : IPhrase
{
public Phrase()
{
}
public int CategoryId { get; set; }
public string PhraseId { get; set; }
public string English { get; set; }
public string Romaji { get; set; }
public string Kana { get; set; }
public string Kanji { get; set; }
}
Here this code returns data and typecasts it to Phrase:
var phrases = db2.Query<Phrase>("SELECT * FROM Phrase", ans);
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans);
What I would like to know is if there is any difference / advantage in my using the IPhrase here or Phrase? Also what advantages are there (if any) in my creating a IPhrase interface in this example. Does that lead to more readable code?
An interface is a contract that guarantees, any class implementing the interface will implement the methods and properties defined in the interface. This allows you to use the interface to create methods, lists, etc. which accept any class that implements the interface e.g.
public interface IExample
{
int GetInt();
}
public void ProcessInt(IExample value)
{
var tempInt = value.GetInt();
// Do processing here
}
This allows any concrete class that implements interface IExample to be passed to this method. The method is assured that any concrete class passed will have the method GetInt implemented.
With objects you can inherit from to things:
Other Objects
Interfaces
Object
If you have an Animal object, a Dog object can inherit from it as it is an animal.
With Object inheritance think of the phrase: I am a ...._yourObject_...
Interface
With an interface you can think of it as a describer for that object. Such as IWalkOnTwoLegs or ICanSwim.
So think of the phrase : I can do ...._yourInterface_..
Now to answer your question, would it make a difference if you use an interface or not?
Well, it wouldn't in this case but if you extend your phrases and create a Question object and a Statement object, for example, and they inherit from Phrase, you have a choice where you can return all phrases (questions and statements) or only phrases that are Questions or only Statements.
You can also apply an interface saying IAmInFrench and IAmInSpanish to your phrase so you can have extended SpanishPhrase and FrenchPhrase objects.
Now you can return either all phrases whether they are questions, statements, in a different language, or you can be specific and return only french phases.
Where I find interfaces are most useful are for registration of different types in unity.
Where it will make a difference:
Where it will definitely make a difference is if there is a property on the object that isn't on the interface, then if you return the interface you will not be able to access that property very easily unless you type cast.
eg:
public class Phrase : IPhrase
{
public Phrase()
{
}
public int CategoryId { get; set; }
public string PhraseId { get; set; }
public string English { get; set; }
}
And interface
public interface IPhrase
{
int CategoryId { get; set; }
}
You will not be able to access the property English if you return the interface:
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans);
var eng = phrases[0].English; //**THIS WONT WORK**
There is no difference between using an interface and a concrete object locally, as in your example. The main difference is when you are sending interfaces vs concrete classes as parameters in APIs or constructors parameters, where is preferably using interfaces so you can achieve decouple and testability.
Still for your question the short answer is no, there is no difference, whether you want to use interfaces or concrete objects as local variables is your own choice (what seems more readable to you). Do not forget that fields and properties are good to be declared as interfaces which provides more flexibility.
One last thing which should be considered when using a concrete object instead of an interface even locally is that you may want someday to change the signature of the method which provides you that object to return another kind of object which implements the same interface, and in that case you should change the local variable too (even if it's not so bad and it happens very rarely I had to note it), as in the following example:
interface IAnimal
{
void Run();
}
class Cat : IAnimal
{
public void Run()
{
//...
}
}
class Dog : IAnimal
{
public void Run()
{
//...
}
}
If in your code you have a method which returns a Cat that you use:
Cat GetAnimal()
{
return new Cat();
}
Cat myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();
Then if you change the GetAnimal signature to return a Dog, your code should be changed in order to compile to:
Dog myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();
But if you are using an interface there are less chances that your code will need to be changed when method's signatures ar changed:
IAnimal myAnimal = GetAnimal(); //this is working whether a Cat or a Dog is received.
myAnimal.Run();
But again this is happening relatively rarely. Sorry for the silly Cat & Dog example!
A class is a template for an object. It is essentially a blueprint. So for a light there a button that is on and off. Say when you call this method a value is sent to some controller that turns it on and off. All you have to do is call the method for on/off and viola it works.
An interface is very similar. Here the on/off method might not be implemented. You actually have to go and write the code to turn the light on and off but you must write the on/off method or it cannot be that interface. Say there is a new type of light that has dimming functionality. An interface allows you to implement this new feature for a different type of light. So its basically telling you that you have to have this stuff done (on/off) for it to be a light but we don't care how you implement it. Some parts of the interface may be implemented for you, but other parts you have to implement.
When would an interface make sense? A situation where you have many objects that are very similar in nature but differ slightly in implementation. For example say you have many types of shapes. Each is going to have an area. The calculation is different for a triangle than it is for a circle. Now say you have hundreds of shapes that need to be constructed, you wouldn't keep making new objects for each type of shape, you would just implement the interface. This gives somebody the power to create shapes, maybe even custom shapes, with similar methods but different implementations.
Your answer depends on the way you want to use your future classes. Interfaces are contracts to ensure descendant classes have all definitions of interface. So This is useful when you want to use polymorphism. in this way, you can define all common specifications of an object in an interface class. Another advantage of interfaces is that your class can inherit from multiple interfaces, which is not allowed for other type of classes in C#. Here is an example code. Hope to be useful for you:
public interface IShape
{
float Area { get; }
float circumference { get; }
}
public class Rectangle : IShape
{
private float l, h;
public Rectangle( float length, float height ) { l = length; h = height; }
public float Area { get { return l * h; } }
public float circumference { get { return ( l + h ) * 2; } }
}
public class Circle : IShape
{
private float r;
public Circle( float radius ) { r = radius; }
public float Area { get { return (float)Math.PI * r * r; } }
public float circumference { get { return (float)Math.PI * r * 2; } }
}
public class SomeClass
{
IShape[] shapes = new IShape[] // Can store all shapes regardless of its type
{
new Rectangle( 10f, 20f ),
new Rectangle( 15f, 20f ),
new Rectangle( 11.6f, .8f ),
new Circle( 11f ),
new Circle( 4.7f )
};
public void PrintAreas()
{
foreach ( var sh in shapes )
Console.WriteLine( sh.Area ); // prints area of shape regardless of its type
}
public void PrintCircumference(IShape shape )
{
Console.WriteLine( shape.circumference ); // again its not important what is your shape, you cant use this function to print its cicumference
}
}
I'm trying to construct a class in c# (5.0) that I can use as a base class and it contains a List, but List could be 2 different types. I want to do the following:
public class BaseC
{
string header { get; set; }
List<object> recs { get; set; }
}
public class derive1: BaseC
{
List<myclassA> recs;
}
public class derive2: BaseC
{
List<myclassB> recs;
}
and importantly what I want to do is return the derived classes from a method in another class:
public BaseC PopulateMyDerivedClass()
{
BaseC b = new BaseC();
b.header = "stuff";
b.recs = FileHelperEngine<myclassB> fhe.ReadStringAsList(x);
}
the main point is that method PopulateMyDerivedClass really does the exact same thing for both derive1 and derive2, just that it returns a different type of list.
I think I need generics. But is that at the base class level and also is PopulateMyDerivedClass then supposed to return a generic? I think that perhaps I am not dealing with polymorhpism, but as you can guess I am new to generics, so struggling.
I think what you want is to make BaseC a generic class and specify the generic when defining the derived classes:
public class BaseC<T>
{
//...
virtual List<T> Recs { get; set; }
}
public class Derived1 : Base<MyClassA>
{
override List<MyClassA> Recs { get; set; }
}
Good point by Alexei Levenkov:
Usual note: DerivedX classes in this case will not have common parent unlike original sample. One may need to add more layer of classes (as non-generic parent of BaseC) or use an interface if DerivedX need to be treated as having common parent/interface.
I get the feeling that your code design could use some rethinking. For one, typically when we talk about "polymorphism", we are usually talking about polymorphic behaviors (methods), rather than members. I think you might want to consider two classes that implement an interface that does all the things you want each class to do (parses data into its own type of list and acts on it as you need it to).
Nevertheless, without getting way into the details of your code, I think something like this might be what you were trying to achieve:
public class BaseC<T>
{
string header { get; set; }
public List<T> recs {get;set;}
}
and
public BaseC<T> PopulateClass<T>()
{
var b = new BaseC<T>();
b.recs = new List<T>();
T first = (T)Convert.ChangeType("1", typeof(T));
b.recs.Add(first);
return b;
}
And to check our sanity:
BaseC<String> d1 = PopulateClass<String>();
System.Diagnostics.Debug.Print(d1.recs.First().ToString());
System.Diagnostics.Debug.Print(d1.recs.First().GetType().ToString());
BaseC<int> d2 = PopulateClass<int>();
System.Diagnostics.Debug.Print(d2.recs.First().ToString());
System.Diagnostics.Debug.Print(d2.recs.First().GetType().ToString());
prints
1
System.String
1
System.Int32
Consider the following class and interfaces:
public interface A { string Property { get; set; } }
public interface B { string Property { get; set; } }
public interface C : A, B { }
public class MyClass : C
{
public string Property { get; set; }
}
Looks simple, right? Now consider the following program:
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Property = "Test";
A aTest = myClass;
B bTest = myClass;
C cTest = myClass;
aTest.Property = "aTest";
System.Console.WriteLine(aTest.Property);
bTest.Property = "bTest";
System.Console.WriteLine(bTest.Property);
cTest.Property = "cTest";
System.Console.WriteLine(cTest.Property);
System.Console.ReadKey();
}
Looks okay, but it will not compile. It gives me an Ambiguity exception:
Why isn't C# able to figure this out? Is what I'm doing crazy from an architectural point of view? I'm trying to understand the why (I know it can be solved with casting).
EDIT
The problems arose when I introduced interface C. When I use MyClass : A, B I've got no problems at all.
FINAL
Just finised a blog about the subject: Interface Ambiguity and Implicit Implementation.
In short because it's ambiguous indeed.
Now more detailed story. As you've already seen there is explicit interface implementation, so you can have two different implementations for A.Property and B.Property and when you have only C there is no way you can tell if implementations are the same or not. Since C# "philosophy" is not to guess what you meant, but make you state it more clear when necessary, compiler does not choose either A.Property or B.Property, but reports an error.
You need explicit interface implementation:
public interface A { string Property { get; set; } }
public interface B { string Property { get; set; } }
public interface C : A, B { }
public class MyClass : C
{
string B.Property { get; set; }
string A.Property { get; set; }
}
When it comes time to call them you are going to have to do:
MyClass c = new MyClass();
Console.WriteLine("Property A is ": ((A)c).Property);
Why don't you do:
public class MyClass : C
{
string B.Property { get; set; }
string A.Property { get; set; }
string B { get { return B.Property; } set { B.Property=value; } }
string A { get { return A.Property; } set { A.Property=value; } }
}
And it should be noted this is bad design, if you are going to expose an interface C, make sure you find a better way to expose A/B.Property.
What's to figure out? cTest is of type "C", and it inherits "Property" from two different classes; the compiler doesn't know which one you want. This sort of behavior is inherited from C++; it's the classic example of "why multiple inheritance is a Pandora's box."
Other object-oriented languages -- Java is a notable example -- avoid this problem by definition : like-named/like-signatured methods are fused in a common descendent.
When you inherit from a single interface the compiler can determine exactly which method you are interested in implementing when you add the new method.
However when multiple interfaces have the same method, the underlying (and correct) assumption is that each interface expects a DIFFERENT implementation for the method, due to the fact that those methods or properties are defined on different interfaces.
So the compiler tells you that these different interfaces require an explicit implementation for each of these properties.
The fact that two interfaces share the same NAME for a property or method is arbitrary - there is no reason to assume that they share anything OTHER then the name, so the compiler protects you from making the mistake of implicitly treating them in the same way.
It is not simple, and it doesn't look simple either. In case of a name collision between two interfaces, .NET needs to ask you which interface are you trying to implement. Its way to ask you this is via the ambiguity error.
If you didn't have this kind of errors, you would end up implementing interfaces by chance.
you need to explicity implement both properties from each interface:
public class MyClass : C
{
string A.Property { get; set; }
string B.Property { get; set; }
}
Because what you are doing is not right. A and B are clashing and have the same name for the property... you need to use Explicit implementation of interface.
Reference here.
There are a lot of answers, and all of them are right, as explicit interface implementation is the answer to your problem.
I'll try to clarify the motivation behind this design with a somewhat convoluted example:
Let's say I have an interface for people that run (with possible implementations like LongDistanceRunner, Jogger, MarathonMan, etc)
public interface IRunner
{
void Run();
}
and an interface for devices that can be turned on and ran (with possible implementations BathTub, Application, Dishwasher, etc)
public interface IRunnable
{
void Run();
}
Now I want to create and interface for a IMusicallJogger (implementations like JoggerWithIpod,BoomBoxJogger, etc)
public interface IMusicalJogger : IRunner, IRunnable {}
public class BoomBoxJogger : IMusicalJogger
{
// code here
}
BoomBoxJogger bbJogger = new BoomBoxJogger();
Now, when I say bbJogger.Run() what should my object do? Should it start running across the park, or should it turn on the boombox, or both, or something else entirely? If I implement both the class and the callsite, it might be obvious that I want my joggers to do both, but what if I control just the callsite? And what if there are other implementations of the interface that do something else? And what if my jogger starts running across the park, when it's used in a context where it is considered like a device (through casting).
That's where explicit interface implementation comes into play.
I have to define my class like this:
public class BoomBoxJogger : IMusicalJogger
{
void IRunner.Run() //implementation of the runner aspect
{
Console.WriteLine("Running through the park");
}
void IRunnable.Run() //implementation of the runnable aspect
{
Console.WriteLine("Blasting out Megadeth on my boombox");
}
public void Run() //a new method defined in the class itself
{
Console.WriteLine("Running while listening to music");
}
}
and then, when I call, I have to specify what aspect of my jogger I want to use:
BoomBoxJogger bbJogger = new BoomBoxJogger();
((IRunner).bbJogger).Run(); // start running
((IRunnable).bbJogger).Run(); // blast the boombox
//and of course you can now do
bbJogger.Run //running while listening
((IMusicalJogger)jogger).Run(); //compiler error here, as there is no way to resolve this.
Hope I helped clarify the concept.