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");
}
}
Related
I want to create an alias for a class name. The following syntax would be perfect:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
but it won't compile.
Example
Note This example is provided for convenience only. Don't try to solve this particular problem by suggesting changing the design of the entire system. The presence, or lack, of this example doesn't change the original question.
Some existing code depends on the presence of a static class:
public static class ColorScheme
{
...
}
This color scheme is the Outlook 2003 color scheme. i want to introduce an Outlook 2007 color scheme, while retaining the Outlook 2003 color scheme:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
But i'm still faced with the fact that the code depends on the presence of a static class called ColorScheme. My first thought was to create a ColorScheme class that I will inherit from either Outlook2003 or Outlook2007:
public static class ColorScheme : Outlook2007ColorScheme
{
}
but you cannot inherit from a static class.
My next thought was to create the static ColorScheme class, but make Outlook2003ColorScheme and Outlook2007ColorScheme classes non-static. Then a static variable in the static ColorScheme class can point to either "true" color scheme:
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
but that would require me to convert a class composed entirly of readonly static Colors into overridable properties, and then my ColorScheme class would need to have the 30 different property getters thunk down into the contained object.
That's just too much typing.
So my next thought was to alias the class:
public static ColorScheme = Outlook2007ColorScheme;
But that doesn't compile.
How can I alias a static class into another name?
Update: Can someone please add the answer "You cannot do this in C#", so I can mark that as the accepted answer. Anyone else wanting the answer to the same question will find this question, the accepted answer, and a number of workarounds that might, or might not, be useful.
I just want to close this question out.
You can’t. The next best thing you can do is have using declarations in the files that use the class.
For example, you could rewrite the dependent code using an import alias (as a quasi-typedef substitute):
using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Unfortunately this needs to go into every scope/file that uses the name.
I therefore don't know if this is practical in your case.
You can make an alias for your class by adding this line of code:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
You cannot alias a class name in C#.
There are things you can do that are not aliasing a class name in C#.
But to answer the original question: you cannot alias a class name in C#.
Update: People are confused why using doesn't work. Example:
Form1.cs
private void button1_Click(object sender, EventArgs e)
{
this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}
ColorScheme.cs
class ColorScheme
{
public static Color ApplyColorScheme(Color c) { ... }
}
And everything works. Now i want to create a new class, and alias ColorScheme to it (so that no code needs to be modified):
ColorScheme.cs
using ColorScheme = Outlook2007ColorScheme;
class Outlook2007ColorScheme
{
public static Color ApplyColorScheme(Color c) { ... }
}
Ohh, i'm sorry. This code doesn't compile:
My question was how to alias a class in C#. It cannot be done. There are things i can do that are not aliasing a class name in C#:
change everyone who depends on ColorScheme to using ColorScheme instead (code change workaround because i cannot alias)
change everyone who depends on ColorScheme to use a factory pattern them a polymorphic class or interface (code change workaround because i cannot alias)
But these workarounds involve breaking existing code: not an option.
If people depend on the presence of a ColorScheme class, i have to actually copy/paste a ColorScheme class.
In other words: i cannot alias a class name in C#.
This contrasts with other object oriented languages, where i could define the alias:
ColorScheme = Outlook2007ColorScheme
and i'd be done.
You want a (Factory|Singleton), depending on your requirements. The premise is to make it so that the client code doesn't have to know which color scheme it is getting. If the color scheme should be application wide, a singleton should be fine. If you may use a different scheme in different circumstances, a Factory pattern is probably the way to go. Either way, when the color scheme needs to change, the code only has to be changed in one place.
public interface ColorScheme {
Color TitleBar { get; }
Color Background{ get; }
...
}
public static class ColorSchemeFactory {
private static ColorScheme scheme = new Outlook2007ColorScheme();
public static ColorScheme GetColorScheme() { //Add applicable arguments
return scheme;
}
}
public class Outlook2003ColorScheme: ColorScheme {
public Color TitleBar {
get { return Color.LightBlue; }
}
public Color Background {
get { return Color.Gray; }
}
}
public class Outlook2007ColorScheme: ColorScheme {
public Color TitleBar {
get { return Color.Blue; }
}
public Color Background {
get { return Color.White; }
}
}
try this:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
I'm adding this comment for users finding this long after OP accepted their "answer".
Aliasing in C# works by specifying the class name using it's fully qualified namespace. One defined, the alias name can be used within it's scope.
Example.
using aliasClass = Fully.Qualified.Namespace.Example;
//Example being the class in the Fully.Qualified.Namespace
public class Test{
public void Test_Function(){
aliasClass.DoStuff();
//aliasClass here representing the Example class thus aliasing
//aliasClass will be in scope for all code in my Test.cs file
}
}
Apologies for the quickly typed code but hopefully it explains how this should be implemented so that users aren't mislead into believing it cannot be done in C#.
Aliasing the way that you would like to do it will not work in C#. This is because aliasing is done through the using directive, which is limited to the file/namespace in question. If you have 50 files that use the old class name, that will mean 50 places to update.
That said, I think there is an easy solution to make your code change as minimal as possible. Make the ColorScheme class a facade for your calls to the actual classes with the implementation, and use the using in that file to determine which ColorScheme you use.
In other words, do this:
using CurrentColorScheme = Outlook2007ColorScheme;
public static class ColorScheme
{
public static Color ApplyColorScheme(Color c)
{
return CurrentColorScheme.ApplyColorScheme(c);
}
public static Something DoSomethingElse(Param a, Param b)
{
return CurrentColorScheme.DoSomethingElse(a, b);
}
}
Then in your code behind, change nothing:
private void button1_Click(object sender, EventArgs e)
{
this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}
You can then update the values of ColorScheme by updating one line of code (using CurrentColorScheme = Outlook2008ColorScheme;).
A couple concerns here:
Every new method or property definition will then need to be added in two places, to the ColorScheme class and to the Outlook2007ColorScheme class. This is extra work, but if this is true legacy code, it shouldn't be a frequent occurence. As a bonus, the code in ColorScheme is so simple that any possible bug is very obvious.
This use of static classes doesn't seem natural to me; I probably would try to refactor the legacy code to do this differently, but I understand too that your situation may not allow that.
If you already have a ColorScheme class that you're replacing, this approach and any other could be a problem. I would advise that you rename that class to something like ColorSchemeOld, and then access it through using CurrentColorScheme = ColorSchemeOld;.
I suppose you can always inherit from the base class with nothing added
public class Child : MyReallyReallyLongNamedClass {}
UPDATE
But if you have the capability of refactoring the class itself: A class name is usually unnecessarily long due to lack of namespaces.
If you see cases as ApiLoginUser, DataBaseUser, WebPortalLoginUser, is usually indication of lack of namespace due the fear that the name User might conflict.
In this case however, you can use namespace alias ,as it has been pointed out in above posts
using LoginApi = MyCompany.Api.Login;
using AuthDB = MyCompany.DataBase.Auth;
using ViewModels = MyCompany.BananasPortal.Models;
// ...
AuthDB.User dbUser;
using ( var ctxt = new AuthDB.AuthContext() )
{
dbUser = ctxt.Users.Find(userId);
}
var apiUser = new LoginApi.Models.User {
Username = dbUser.EmailAddess,
Password = "*****"
};
LoginApi.UserSession apiUserSession = await LoginApi.Login(apiUser);
var vm = new ViewModels.User(apiUserSession.User.Details);
return View(vm);
Note how the class names are all User, but in different namespaces. Quoting PEP-20: Zen of Python:
Namespaces are one honking great idea -- let's do more of those!
Hope this helps
Is it possible to change to using an interface?
Perhaps you could create an IColorScheme interface that all of the classes implement?
This would work well with the factory pattern as shown by Chris Marasti-Georg
It's a very late partial answer - but if you define the same class 'ColorScheme', in the same namespace 'Outlook', but in separate assemblies, one called Outlook2003 and the other Outlook2007, then all you need to do is reference the appropriate assembly.
The best way I've found to simulate alias in C# is inheritance.
Create a new class that inherits from the original class:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName
: LongClassNameOrOneThatContainsVersionOrDomainSpecificName
{
}
The only thing that you would need to be careful is the constructor. You need to provide a a constructor for MyName class.
public class MyName
: LongClassNameOrOneThatContainsVersionOrDomainSpecificName
{
public MyName(T1 param1, T2 param2) : base(param1, param2) {}
}
In this example I'm using T1 and T2 as generic types, since I don't know the constructor for your LongClassNameOrOneThatContainsVersionOrDomainSpecificName class.
Beware, though, that this is not alias. Doing this to you application might run into some issues or problems. You might need to create some extra code to check for types, or even overload some operators.
i know the model should not have any logic , but i don't know where is the good place to put the checking or the update function for a particular model
ex.
public class GuestBook
{
public int money { get; set; }
[Required]
public string name { get; set; }
[Required]
public string email { get; set; }
public DateTime content { get; set; }
public bool rich()
{
if (this.money <3000)
return false;
else
return true;
}
public void earn(GuestBook b)
{
this.money += b.money;
}
}
the function rich() and earn() is only use for this module(GuestBook)
if i didn't put it in this module , then where i should put?
Following good OOP design principles, the only way to really protect your classes' invariants (and not have a maintainability nightmare) is by not allowing them to be changed by anyone other than the class. Typically this is done by NOT exposing public setter methods (public auto properties are evil), making your fields readonly (wherever possible), and initializing them from the constructor.
The whole point of having classes is to group data with behavior. A simple data structure containing ints and strings is not a class in the OOP sense, it's just a struct.
In some cases you are stuck with an even more evil ORM that FORCES you to make all properties public. This is not an issue with Entity Framework (and some others too) though, EF can magically reflect in and access private setters if needed, you just gotta make sure there's also a private default constructor.
According to your class rich method is validating and earn method is applying business logic. You can create AdditionalMetadataAttribute for rich method logic that can fire on ModelState.IsValid and for earn method you need to create BO class that apply your all business logic.
here a link for AdditionalMetadataAttribute
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.
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
}