I created an abstract class that implements an interface. This abstract class will be the base of several concrete classes that need to populate the properties of that interface.
The CLR compliance warnings pop up on the first two examples. I understand what they represent and there are several questions here that cover them.
To make the field different I can add a trailing underscore. It is accepted by the compiler. Is this a correct style choice. I don't think it stands out very well and may be a code smell. But I may just not be used to it.
Or am I wrong to make an abstract ancestor that defines property fields? The idea of course is to save duplication of work and help to enforce a standard implementation, but I can see that it might have its own smell in the descendent when it starts assigning values to these "hidden" fields.
namespace MyLittleCompany.Widgety
{
public abstract class MlcWidgetInformation : IMlcWidgetInformation
{
//Compiler complains of Non-CLR Compliance (case difference only)
protected int sides; //Number of sides for this widget
//Compiler complains of Non-CLR Compliance (non-private name with underscore
// is not compliant)
protected int _hooks; //Number of hooks on this widget
//Compiler is happy with a trailing underscore
protected int feathers_; //Number of feathers on this widget
// Interface items
public Sides { get { return sides; } }
public Hooks { get { return _hooks; } }
public Feathers { get { return feathers_; } }
}
}
=====================================
namespace MyLittleCompany.Widgety
{
public class SmallWidgetInformation : MlcWidgetInformation
{
public SmallWidgetInformation()
{
// Is this a smell? As in "What are these things?"
sides = 6;
_hooks = 3;
feathers_ = 1;
}
}
}
Having to create an abstract base class just to avoid repeatedly defining three fields isn't a code smell, but:
It does feel like taking DRY to extremes,
and (assuming you use inheritance elsewhere), you block the opportunity to inherit from other classes.
However, if you are willing/able to use VS2015 and C# 6, help is at hand. The new read-only auto properties allow you to do this, removing the need for the base class without repetition:
public interface IMlcWidgetInformation
{
int Sides { get; }
int Hooks { get; }
int Feathers { get; }
}
public class SmallWidgetInformation : IMlcWidgetInformation
{
public int Sides { get; } = 6;
public int Hooks { get; } = 3;
public int Feathers { get; } = 1;
}
Until C# 6 becomes more widely adopted, you are left choosing between inheritance and repeating yourself.
It's absolutely accepted to make protected fields in abstract classes.
Naming conventions are guidelines only and it depends on the styling tool you are using. Use the style that you and/or your team preffer and customize your tool from that. The most important thing is that the project is consistent in its own.
I've personally never seen the trailing underscore in use before, but I can see the benefit in it. Might be a pretty smart way to show protected fields. I would definately approve of that convention if I ran into a team that used it.
Related
I have an abstract class called Flight and its implement a interface called IFlight and it has a virtual method, another three classes that inherit from it, the only diffrence between those three classes is the implemantation of this method. Another thing that I want to do is implement a method that accepts as an argument an object of type IFlight (could be one of those three classes) and from them i want to access the members of the abstract class (Flight). Which way there is to implement such thing ?
Flight:
class AbsFlight: IFlight
{
public int ID { get; set; }
public string Start_Point { get; set; }
public virtual float Calculate_Price(float Base_Price)
{
return Base_Price;
}
}
One of the classes (The other two looks similar except the method "Calculate_Price"):
class Charter: AbsFlight
{
public override float Calculate_Price(float Base_Price)
{
return base.Calculate_Price(Base_Price) * 3;
}
}
Main:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2)); //OK
Console.WriteLine(flight.ID); //Error
}
static void Main(string[] args)
{
List<IFlight> flights = new List<IFlight>();
flights.Add(new Regular());
flights.Add(new Charter());
flights.Add(new LowCost());
Main_SomeMethod(flights[0]);
}
Your current solution, in combination with some of the suggestions, will be a case of a mounted riding rider. You don't need an interface and a base class and testing for type.
You can solve your problem the way you're trying, with a base class and an interface. But it's overkill, and you have to kind of duplicate some stuff in the interface and the base class.
You can solve your problem with a simple base class and three derived classes where only Calculate_Price gets overridden. Put the common items in the base class. This is a very simple solution, easy to figure out, especially if C# and OOP is new to you.
You can also solve your problem with an interface and three classes, not derived. This has the disadvantage that you have to implement the interface in three classes. As Peter Csala points out, C# 8 has some language features that can help minimize this work, possibly making this just as simple as using only a base class and no interface. I am not too familiar with those features, so I can't judge whether it makes sense.
Then there is another option entirely. This touches on what zaitsman hinted at - that this is possibly an XY problem. Why do you want to distinguish between Regular, Charter and LowCost using classes derived from Flight/AbsFlight? Is it possible to just have an attribute that tells what price profile is used? Are there other fields and properties of a Flight that has nothing to do with the price, and yet also distinguishes flights? Perhaps just use one class.
About testing for class type. This is what we call code smell. Generally, if you test for class types a lot, then you defy the purpose of using classes and/or interfaces in the first place.
Your method should accept the type that has the properties it needs, in this case the AbsFlight class.
private static void Some_Method(AbsFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
Console.WriteLine(flight.ID); //OK
}
But let's says the method must accept any IFlight. In this case, it can't be sure it received an AbsFlight; it has to check. After the check you can just cast.
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
if (flight is AbsFlight)
{
Console.WriteLine(((AbsFlight)flight).ID); //OK
}
}
With c#7 there is an additional construct you can use, if you think it is clearer:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
switch (flight)
{
case AbsFlight absFlight:
Console.WriteLine(absFlight.ID); //OK
break;
}
}
It seems to be that you are doing something wrong that this is your requirement.
When you use an interface and pass it as an argument you want it to be common to all the objects that implement it.
Anyway, if you do want to do it. You might do something like:
if (flight is Flight)
{
Flight yourFlight = (Flight)flight;
// Here you can use anything you need from Flight, e.g: yourFlight.ID
}
I have a question about naming multiple classes that share similar functionality. I am working on a scientific API and have the following classes/interfaces:
public interface IRange<T>{
T Minimum {get;}
T Maximum {get;}
// A few other methods that aren't important
}
public class Range<T> : IRange<T> where T: IComparable<T> {
public T Minimum {get; protected set;}
public T Maximum {get; protected set;}
public Range(T minimum, T maximum) {
Minimum = minimum;
Maximum = maximum;
}
}
For my API, I work with double ranges a lot (i.e., Range<double>), so I made an another class called MassRange. This class also has a few new constructors and properties shown below:
public class MassRange : Range<double>, IRange<double> {
public double Width { get { return Maximum - Minimum;} }
public double Mean { get { return (Maximum + Minimum) / 2.0;} }
public MassRange(double mean, MassTolerance width) {
Minimum = mean - width.Value; // pseudo-code
Maximum = mean + width.Value;
}
}
Conceptually, I also have another type of Range<double> called a MzRange, that shares all the same structure and functionality as MassRange but I want to keep separate in the API. They act exactly the same and store the same types of data, but in terms of the science, they are different and distinct.
So I considered renaming the MassRange class to a more generic name of DoubleRange and then have both MassRange : DoubleRange and MzRange : DoubleRange designed like so:
public MzRange : DoubleRange, IRange<double> {}
public MassRange : DoubleRange, IRange<double> {}
But I don't really care for the name DoubleRange, and would rather not expose it publicly through my API. Is exposing two distinct types with the same functionality even appropriate? Should I just come up with a better name for DoubleRange and forgo MzRange and MassRange? Can I make DoubleRange internal or something so that it is not exposed through the API but can still be used?
This seems to be a case for Extension Properties but I know they don't currently exist.
There doesn't seem to be any reason you can't accomplish this with standard extension methods:
public static double GetWidth(this IRange<double> range) {
return range.Maximum - range.Minimum;
}
public static double GetMean(this IRange<double> range) {
return (range.Maximum + range.Minimum) / 2.0;
}
And then you can call it from any implementation of IRange:
var massRange = ...
var mean = massRange.GetMean();
I know it may not have the syntactic appeal of extension properties, but it's a clean solution that gets around having to create that DoubleRange class.
This is absolutely appropriate. Besides the logical distinction, it gives you the possibility to evolve the two classes independently from each other in future.
Even if elephants and birds are animals (both inherit from animals) and both have the same set of properties (they don't add or override members), you might want to add a Fly method to birds in future. I assume that elephants named Dumbo do not exist in real world scenarios :-)
Having two types with the exact same functionality isn't appropriate as any change made to one type will need to be made to the other.
Unless you know that MassRange and MzRange will be differentiated at some point in the future, providing a better name for DoubleRange and forgoing MassRange/MzRange is the way to go. And even then, any shared functionality would need to be put in a parent type.
You can always provide some syntactic sugar to help users. For instance, you could create "dumb" classes called MassRange and MzRange, which simply extend DoubleRange. I'd keep the original, well named class exposed, to encourage users to use it, but if you really want to hide it, just use the protected accessor instead of public.
Im starting a new project and i have some problem trying to implement some naming conventions.
I used to work with Classes starting with Uppercase and Singular, like Car or User, and my variables starting with lower case, so if I needed to declare a class that had some variables of type Car and User i would do it like this:
public Car car;
private User user;
Now im trying to use some properties and as i see they should also be PascalCase , wich mean if i need to declare the same examples i would be:
public Car Car { get; set; }
private User User { get; set; }
And you can all see what would the problem be here, or you don't see it as a problem?
So what should i do? what am i missing here?
The C# naming convention recommends everything that is public as well as classes, interfaces etc., to start with an uppercase letter. The rest should start lower case.
There is no problem with:
private User User { get; set; }
... since the position of each name (word) defines what is what.
The English language works the same way.
e.g.: "I love love." (pronoun, verb, noun)
What you're run into is called the Color Color problem, because the most common way it crops up is "I need a property called Color of a type called Color". C# has been specifically designed to manage Color Color situations elegantly.
For details, read section 7.6.4.1 "Identical simple names and type names" in the C# 4 specification.
The rules for Color Color situations are a bit complicated (believe me, they do not make the compiler implementer's life any easier!) and they can lead to some interesting corner cases. If this subject interests you then you should read my article on it:
http://blogs.msdn.com/b/ericlippert/archive/2009/07/06/color-color.aspx
I think in many cases the context means you'd have a specific name - e.g. Car customersCar, etc.
Saying that, many people don't have an issue with the name/type being the same - see this link:
Should a property have the same name as its type?
For naming conventions in general, following MS isn't a bad start -
http://msdn.microsoft.com/en-gb/library/vstudio/ms229045(v=vs.100).aspx
There is no issue here; As #NDJ suggested you can apply context to add additional prefix to the property if you do not feel comfortable; but this will not generally add additional meaning to the context.
As a general Microsoft style guide encourages the use of Pascal Case for properties.
For a more complete guide on capitalization see the following MSDN article
There is no problem there.
Because in the context where you would use the class it can not be misstaken for the property and vice versa.
Edit: Ok, Im going to assume you have the Userclass inside the carclass like this:
public class Car
{
private class User
{
}
private User User
{
get;
set;
}
}
Which indeed would create problems. Move out your user and the problem is solved.
public class Car
{
private User User
{
get;
set;
}
}
public class User
{
}
Barring the internal class problem that #Evelie pointed out you should not have any issue naming a property the same as the type - in fact this is not an uncommon practice. .NET has public Color Color properties all over the place.
As the following program illustrates the compiler can distinguich between instance calls and static calls:
void Main()
{
Car c = new Car();
c.Test();
}
public class Car
{
public Car()
{
User = new User();
}
public void Test()
{
User.Static(); // calls static method
User.Instance(); // implies this.User
}
public User User { get; set; }
}
// Define other methods and classes here
public class User
{
public static void Static()
{
Console.WriteLine("Static");
}
public void Instance()
{
Console.WriteLine("Instance");
}
}
I have a library (no source), to an certain object of which, I need to add some properties.
What would be the a way to do it ? I'm aware I could extend the class and add properties to the child. As well I know there are NO Extension Properties in C# yet. What would you suggest ? Thank you !
The metadata of class could be something like :
public class ResultClass
{
public IList<Item> Results { get; set; }
public int TotalResults { get; set; }
}
and I want to add a :
String description;
to it. Thanks.
There are a couple strategies you could take. Inheritance is the most obvious one. You might also consider composition. Can you give us some more details about what the object is and what properties you need to add to it and why?
After seeing the expanded question:
Either strategy outlined above (composition or inheritance) will probably work for you. Personally, I prefer composition. I think it better insulates you from changes that might be made to the third party library. It also forces you to work through the public interface of the library class, which is preferable when you have no knowledge or control of the internals of a class.
Here is the most basic example of composition.
public CompositeClass
{
private ResultClass _resultClass = new ResultClass();
public IList<Item> Results
{
get { return _resultClass.Results; }
set { _resultClass.Results = value; }
}
public int TotalResults
{
get { return _resultClass.TotalResults; }
set { _resultClass.TotalResults = value; }
}
//
// New Property
//
public string Description { get; set; }
}
Why do you need to add properties? If this is for binding purposes then I would suggest creating a wrapper class or creating your own inherited type that can raise PropertyChanged events in response to various state changes in your third party types. Instead of telling us your proposed solution you should tell us the actual problem you are trying to solve. Also (as I can't vote to close/migrate), this is not really a valid discussion for this site.
I think you are mixing up Extension Methods with Extension Properties.
And the last ones do not exist in C#.
So you should extend the class or create an inheriting class.
I previously posted this, but I guess it was too verbose and irrelevant. My question is also like this. One poster in the second link said the answer (of why you can't do the code below) was a problem of design, specifically "bad use of inheritance". So I'd like to check this issue again with the experts at StackOverflow and see if this is really an issue of "bad inheritance" - but more importantly, how to fix the design.
Like the poster, I'm also confused about the Factory method and how I can apply it. It seems the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class and do not add their own properties. But, as you will see below, my concrete classes build upon the abstract base class and add extra properties.
The Base Class We Build Upon:
public abstract class FlatScreenTV
{
public string Size { get; set; }
public string ScreenType { get; set; }
}
Extension Class Examples:
public class PhillipsFlatScreenTV : FlatScreenTV
{
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity { get; set; }
}
public class SamsungFlatScreenTV : FlatScreenTV
{
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime { get; set; }
}
Let's say there are more extension classes for more brands of flat screen TVs. And then, let's say we stick them all into a generic List:
public static void Main()
{
List<FlatScreenTV> tvList = new List<FlatScreenTV>();
tvList.Add(new PhillipsFlatScreenTV());
tvList.Add(new SamsungFlatScreenTV());
tvList.Add(new SharpFlatScreenTV());
tvList.Add(new VizioFlatScreenTV());
FlatScreenTV tv = tvList[9]; // Randomly get one TV out of our huge list
}
The Problem:
I want to access the specific properties of whatever 'original' brand TV this variable belongs to. I know the brand because if I call tv.GetType(), it returns the correct 'original' type - not FlatScreenTV. But I need to be able to cast tv from FlatScreenTV back to its original type to be able to access the specific properties of each brand of flat-screen TVs.
Question #1: How can I dynamically cast that, properly - without makeshift hacks and huge if-else chains to brute-guess the 'original' type?
After browsing around similar design issues, most answers are: you can't. Some people say to look at the Factory Pattern, and others say to revise the design using interfaces, but I don't know how to use either to solve this problem.
Question #2: So, how should I design these classes so that I can access the original type's specific properties in the context above?
Question #3: Is this really bad inheritance?
Your design violates the "Liskov Substitution Principle". In other words, the code that deals with items from your list of FlatScreenTV shouldn't know or care what derived type is.
Say your code needs to create a custom remote control GUI. It might be enough to simply know the names and types of the properties of each TV to auto-generate the UI. In which case you could do something like this to expose the custom properties from the base class:
public abstract class FlatScreenTV
{
public FlatScreenTV()
{
CustomProperties = new Dictionary<string,object>();
}
public Dictionary<string,object> CustomProperties { get; private set; }
public string Size { get; set; }
public string ScreenType { get; set; }
}
public class PhillipsFlatScreenTV : FlatScreenTV
{
public PhillipsFlatScreenTV()
{
BackLightIntensity = 0;
}
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity
{
get { return (double)CustomProperties["BackLightIntensity"]; }
set { CustomProperties["BackLightIntensity"] = value; }
}
}
public class SamsungFlatScreenTV : FlatScreenTV
{
public SamsungFlatScreenTV()
{
AutoShutdownTime = 0;
}
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime
{
get { return (int)CustomProperties["AutoShutdownTime"]; }
set { CustomProperties["AutoShutdownTime"] = value; }
}
}
If you really do need to be working directly with the derived types, then you should instead consider moving to a plugin based architecture. For example, you might have a factory method like this:
IRemoteControlGUI GetRemoteControlGUIFor(FlatScreenTV tv)
which would scan your plugins and find the one that knew how to build the UI for the particular type of FlatScreenTV you passed in. This means that for every new FlatScreenTV you add, you also need to create a plugin that knows how to make its remote control GUI.
Factory Pattern would be the best way to go
I can offer a partial answer:
Firstly read up on Liskov's Substitution Principle.
Secondly you are creating objects that inherit from FlatScreenTV, but apparently for no purpose as you want to refer to them by their SubType (SpecificTVType) and not their SuperType (FlatScreenTV) - This is bad use of Inheritance as it is NOT using inheritance lol.
If your code wants to access properties particular to a given type, then you really want this code encapsulated within that type. Otherwise everytime you add a new TV type, all the code that handles the TV list would need to be updated to reflect that.
So you should include a method on FlatScreenTV that does x, and override this in TV's as required.
So basically in your Main method above, instead of thinking I want to be dealing with TVTypeX, you should always refer to the basetype, and let inheritance and method overriding handle the specific behaviour for the subtype you are actually dealing with.
Code eg.
public abstract class FlatScreenTV
{
public virtual void SetOptimumDisplay()
{
//do nothing - base class has no implementation here
}
}
public class PhilipsWD20TV
{
public int BackLightIntensity {get;set;}
public override void SetOptimumDisplay()
{
//Do Something that uses BackLightIntensity
}
}
"the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class [interface] and do not add their own properties."
No, speaking more practical, than theorical, the factory method can provide you with objects of concrete classes, in which the concrete classes, must have some common methods and interfaces, but, also some additional specific attributes.
Sometimes I use a method that creates the same class object every time I called, and I need to call it several times, and sometimes I use a method that create several different class objects, and that maybe be confusing, maybe another question.
And, your further comment about a switch sentence, with many options, when using the factory pattern, you usually provide an identifier for the concrete class / concrete object. This can be a string, an integer, an special type id, or an enumerated type.
You could use an integer / enum ID instead, and use a collection to lookup for the concrete class.
You can still leverage a factory. The point of a factory IMO is to put all the heavy lifting of constructing your various TVs in one place. To say categorically "a factory is for multiple concrete classes that have the exact same implementation as the abstract base class" is forgetting about polymorphism.
There is no law that says you cannot use a factory pattern because the sub classes declare unique properties and methods. But the more you can make use of polymorphism, the more a factory pattern makes sense. Also as a general guideline, IMHO, the more complexity that must go into constructing from the base the better off you are in the long run using a factory because you are "encapsulating change" - that is, constructing concrete classes is likely to change due to differing requirements and inherent construction complexity (a design analysis decision, to be sure) . And that change is in a single class - the factory.
Try this: Define everything in the abstract class and then for a given TV subclass either write concrete-specific code, and for those that don't apply write some standard "I don't do that" code.
Think about all the things your TVs do in generic terms: turn on, turn off, etc. Write a virtual method shell in the base class for all the generic things a TV does - this is a simple example of the template method pattern by the way. Then override these in the concrete classes as appropriate.
There are other things you can do in the base class to make it more fundgeable (that's a technical term meaning "reference subclasses as the base class, but do sub-classy things").
Define delegate methods (very powerful yet under-utilized)
use params[] for dynamic method parameter lists
Make Property delegates
Static methods
Declare Properties and methods "abstract" - forces sub-class implementation, vis-a-vis "virtual"
Hide inherited stuff in the sub class (generally using "new" keyword to communicate that it's on purpose)
If construction parameters are numerous or complex, create a class specifically designed to pass configuration to the factory's build method.
public class TVFactory {
public TV BuildTV(Brands thisKind) {
TV newSet;
switch (thisKind) {
case Brands.Samsung :
Samsung aSamsungTV = new Samsung();
aSamsungTV.BacklightIntensity = double.MinVal;
aSamsungTV.AutoShutdownTime = 45; //oops! I made a magic number. My bad
aSamsungTV.SetAutoShutDownTime = new delegate (newSet.SetASDT);
newSet = aSamsungTV;
break;
. . .
} // switch
}
//more build methods for setting specific parameters
public TV BuildTV (Brands thisKind, string Size) { ... }
// maybe you can pass in a set of properties to exactly control the construction.
// returning a concrete class reference violates the spirit of object oriented programming
public Sony BuildSonyTV (...) {}
public TV BuildTV (Brands thisKind, Dictionary buildParameters) { ... }
}
public class TV {
public string Size { get; set; }
public string ScreenType { get; set; }
public double BackLightIntensity { get; set; }
public int AutoShutdownTime { get; set; }
//define delegates to get/set properties
public delegate int GetAutoShutDownTime ();
public delegate void SetAutoShutDownTime (object obj);
public virtual TurnOn ();
public virtural TurnOff();
// this method implemented by more than one concrete class, so I use that
// as an excuse to declare it in my base.
public virtual SomeSonyPhillipsOnlything () { throw new NotImplementedException("I don't do SonyPhillips stuff"); }
}
public class Samsung : TV {
public Samsung() {
// set the properties, delegates, etc. in the factory
// that way if we ever get new properties we don't open umpteen TV concrete classes
// to add it. We're only altering the TVFactory.
// This demonstrates how a factory isolates code changes for object construction.
}
public override void TurnOn() { // do stuff }
public override void TurnOn() { // do stuff }
public void SamsungUniqueThing () { // do samsung unique stuff }
internal void SetASDT (int i) {
AutoShutDownTime = i;
}
}
// I like enumerations.
// No worries about string gotchas
// we get intellense in Visual Studio
// has a documentation-y quality
enum Brands {
Sony
,Samsung
,Phillips
}