I hate writing repetitive code....
In my current project I need to write properties that looks the same in each class, but different from class to class.
My wish is to generate custom properties from private memeber variables. Lets say I have declared a Name variable like this.
private string Name;
In my first class I want to automagically generate a property like this:
private string m_name;
public string Name
{
get
{ return m_name; }
set
{
m_name = value;
// some code....e.g.
m_counter++;
}
And maybe I want another implementation in my second class, e.g.
private string m_name;
public string Name
{
get
{ return m_name; }
set
{
// some code....e.g.
if(MyValidationFramework.Validate("Name", value))
{
m_name = value;
}
}
I know I can create my own snippets. Since I often change the property-implementation I'd like a way to generate the properties from a template, then change the template and generate properties again. Can this be done?
Thanks!
This is not direct answer to you question. However, with the example you show, why not to have a base class and inherit from it, like this:
public abstract class BaseClass
{
private string m_name;
public string Name
{
get { return m_name; }
set
{
if (BeforeNameSet(value))
m_name = value;
}
}
public virtual bool BeforeNameSet(string name)
{
return true;
}
}
public abstract class ChildClass : BaseClass
{
public override bool BeforeNameSet(string name)
{
// do the part that is different
return false;
}
}
[Edit]
I see you that snippets are not an option for you.
You could create an item template, (How to: Manually Create Item Templates), but in the end this is even more effort as you want to be able to dynamically update those. Item template is a zip file, that you would need to change content for.
Seems like copy/paste is your best option then.
Related
I've made a class with T. It looks like this.
public interface ISendLogic<T> where T : NarcoticsResult
{
ChangeType Change_New();
ChangeType Change_Cancel();
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
private eReportType _type;
private bool Send_Change()
{
// Send to server by xml file
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public ChangeType Change_New()
{
_type = change_new;
Send_Change();
}
public ChangeType Change_Cancel()
{
_type = change_cancel;
Send_Change();
}
public PurchaseType Purchase_New()
{
_type = purchase_new;
Send_Purchase();
}
public PurchaseType Purchase_Cancel()
{
_type = purchase_cancel;
Send_Purchase();
}
}
There are two types, ChangeType and PurchaseType
and these are inherited from NarcoticsResult.
I thought the person who want to use this class would use it like this.
// this class can only be used when someone wants to use change function
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();
Here is a question.
I want to force this class to be used only as I thought.
I mean, I want to prevent it to be used like this.
var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()
I thought I add some code which check type of T in every function.
How do you think the way I thought. I think there are better way to fix it
Please tell me a better way
thank you.
Personally, I don't think you need a generic class in this case. What you need is either an abstract base class or an interface. I personally love the interface approach as below:
public interface ISendLogic {
void New();
void Cancel();
}
So now you've got a contract that will force the consumer of your code to use New or Cancel methods only.
The next step you can implement that send logic interface for your specific implementation:
public class ChangeSendLogic : ISendLogic {
private eReportType _type;
public ChangeSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Change()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Change();
}
public void Cancel()
{
_type = change_cancel;
Send_Change();
}
}
public class PurchaseSendLogic : ISendLogic {
private eReportType _type;
public PurchaseSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Purchase();
}
public void Cancel()
{
_type = change_cancel;
Send_Purchase();
}
}
From here you can see those two classes handle the implementation for each type nicely. You can think this is as an implementation of single responsibility principle. So if you have one more type, you can just add one more implementation of this interface rather than updating the existing classes.
If you want to hide the creation of those objects, in the next part you can introduce a kind of factory or selector as below:
public enum SendLogicType {
Change,
Purchase
}
public static SendLogicSelector {
public static ISendLogic GetSendLogic(SendLogicType type)
{
switch(type)
{
case SendLogicType.Change:
return new ChangeSendLogic();
case SendLogicType.Purchase:
return new PurchaseSendLogic();
}
}
}
This is how the code will be consumed:
ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed
sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed
Hopefully, you can get the idea of my approach. Good luck! :)
Thank you for your comment
I divided it into two parts like below
public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic
And I also divided interface too
public interface IChangeLogic
{
ChangeType Change_New();
ChangeType Change_Cancel();
}
public interface IPurchaseLogic
{
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
And I made SendLogic<T> class to abstract class.
This is because I want to make the person who wants to use this class to use a class that inherits from this class without directly accessing it.
Thank you for your comment. I got a good idea.
Problem
I have a design issue I can't solve clevely. I'm sure there's an elegent solution, but I can't figure out how achieve it. I still managed to my my code work, but the result is ugly, and I want to learn better designs.
I did my best to provide a minimal implementation with only the bare minimum. Some aspects might therefore look weird. I hope I will get myself clear.
Context
So first, I have these simple classes that both implement the same interface:
public interface Human
{
string getName();
}
public class Adult : Human
{
public Adult(string name, string job)
{
Name = name;
Job = job;
}
public string Name { get; set; }
public string Job { get; set; }
public string getName()
{
return Name;
}
}
public class Child : Human
{
public Child(string name, string toy)
{
Name = name;
Toy = toy;
}
public string Name { get; set; }
public string Toy { get; set; }
public string getName()
{
return Name;
}
}
I use those classes in another, more complex class, that basically have the folloing structure:
class MasterClass
{
public string Name;
public string Job;
public string Toy;
private ObservableCollection<Adult> ListOfAdults;
private ObservableCollection<Child> ListOfChildren;
private ObservableCollection<Human> CurrentList; // Will point to one of the above list
public void InitiateLists()
{
// Populate above lists with data
}
public Human CurrentHuman;
public void ManageAdults()
{
CurrentList = new ObservableCollection<Human>(ListOfAdults);
}
public void ManageChildren()
{
CurrentList = new ObservableCollection<Human>(ListOfChildren);
}
public void setOtherHuman()
{
// Sets CurrentHuman as another adult/child according to currently managed list
}
public void SetManager(string newType)
{
switch (newType)
{
case "adult":
ManageAdults();
break;
case "child":
ManageChildren();
break;
}
}
void UpdateInfo()
{
// Set Name and Toy/Job according to currently managed human
}
void PrintInfo()
{
// Print Name and Toy/Job according to currently managed human
}
}
This is the skeleton of my current implementation, with aspects I can't modify due to other constraints. In this class, I want the methods PrintInfo() and UpdateInfo() to behave differently depending if the CurrentHuman is an Adult or a Child.
So far
I managed to make it work with a swich-case in both methods and some cast. Like this:
void UpdateInfo(string currentType)
{
Name = CurrentHuman.getName();
switch (currentType)
{
case: "adult":
Job = ((Adult) CurrentHuman).Job;
break;
case: "child":
Toy = ((Child) CurrentHuman).Toy;
break;
}
}
This is really not ideal though. In my actual design, I have a lot more types, and other methods that behave differently according to the type of the CurrentItem. So I'm now drowning in switch-cases. This makes my code messy, duplicated and very hard to maintain.
Possible solution with interfaces
Since I just discovered them, I thought I could use interfaces. I did my best, but couldn't get a solution to work.
I imagined a simple interface like so:
public interface IUpdater
{
void UpdateData(); // Takes the values from CurrentHuman and store them in the private members Name and Job/Toy depending on current type.
void Print();
}
I also implement my interface in two different ways:
class AdultUpdater : IUpdater
{
public void Print()
{
// Print Adult stuff only
}
public void UpdateData()
{
// Update Adult data only.
}
}
and a similar class ChildUpdater : IUpdater. They both implement the dedicated code for the Child/Adult.
If I declare a private IUpdater Updater as private member of my MasterClass, this allows me to change my methods ManageAdult()and ManageChildren() like this:
public void ManageAdults()
{
CurrentList = new ObservableCollection<Human>(ListOfAdults); // Same as before
Updater = new AdultUpdater(); // Specify implementation to use
}
(similar for ManageChildren()).
I can then brilliantly implement my UpdateInfo() like this:
void UpdateInfo()
{
Updater.UpdateData();
}
and my PrintInfo() method like this:
void PrintInfo()
{
Updater.Print();
}
Interfaces are truly amazing! Oh but wait...
New problem
This seems very promising. My problem is that I don't know how to implement the code of my class AdultUpdater() and class ChildUpdater(). More precisely, these two classes need to access private members of the MasterClass, namely the members Name, Job and Toy. The UpdateData() need to modify them, and the Print() need to display them. I feel so stupidely stuck at this point, so close to a very elegent solution. Does someone have an idea how to finalize this design?
Thank you for reading... I'm sorry if this issue could have been reduced to a more concise question. I had the feeling some details about my current implementation were necessary to get a suitable answer.
As I see it, you are trying to "manage" your humans. Just let them self do the job.
f.e. Don't Print from the manager/masterclass and decide, what to print, but get the printed data (even if only parts, but the parts that are different) from humans and just put it all together in the masterclass.
Use Polymorphism for you. They (your objects/humans) already know, what to print out or update, so let them do the Job. Try to spread the work, instead of pulling it all into one class.
Here is what I advise,
You have a Human class which corresponds to your IHuman, something like this
public class Human : IHuman
{
public Human(string name, string job)
{
Name = name;
Job = job;
}
public string Name { get; set; }
public string Job { get; set; }
public string getName()
{
return Name;
}
}
Your adult and child class would then Inherit the Human class and pass back the constructor values.
public Adult(string name, string job) : base (name, job)
{
}
When you create an instance of adult, you will pass in the name and job, and you can call getName because it will be inherited from the Human class.
Trying to get the reason behind it.
Scenario#1
public class Customer
{
string _name = "Ram";
//now trying to assign some new value to _name on the next line
_name // this property is inaccessible on this line.
}
Scenario#2
public class BaseCustomer
{
protected string _name;
}
public class DerivedCustomer : BaseCustomer
{
_name //inaccessible here
public void SetName()
{
_name = "Shyam"; //accessible here
}
}
Can somebody please let me know what is cause behind this??
Simple. You can't make variable assignments (without declaration) in the class context. You need to use a constructor to put the assignment in:
public class DerivedCustomer : BaseCustomer
{
public DerivedCustomer()
{
_name = "hello";
}
...
}
... or put it in the declaration:
public class BaseCustomer
{
protected string _name = "hello";
}
Note: Experts will probably find exceptions to my simplified explanation. I'm keeping it simple for the sake of explaining the key intention to OP.
In a way, a class really only contains declarations. This can be a field:
public class Customer
{
private string _name;
}
Or a property:
//Example 1 - Simple property
public class Customer
{
public string Name { get; set; }
}
//Example 2 - Publically gettable (but not settable) property with private field (which is settable)
public class Customer
{
private string _name; //this is a field
public string Name => _name; //this is a property that relies on the field
}
Or a method:
public class Customer
{
public string GetName()
{
return "John";
}
}
Boiling it down, I would summarize it as follows:
A class only contains declarations of how it is structured: fields, properties, methods.
A class does not directly contain code (i.e. logic which uses the fields/properties).
However, a class' method or property can contain code (i.e. logic which uses the fields/properties), but this code is considered to be part of the method/property, not part of the class (directly).
What you're trying to do doesn't quite make sense to me. I'm not quite sure what you're hoping to achieve by trying to access the _name in those locations.
It only makes sense to reference this field in the locations where you can reference it:
In a method body - If you need the field during the method's execution
In a property - When the field is used during the set/get of a property
In a constructor - To set the value of the field.
But you're trying to put in in the class. This raises many questions:
What are you trying to do with _name?
Assuming you could reference the field where you want to; when are you expecting this code to be executed?
How would this be any different from simply using a method (or the constructor)?
This seems like an odd request, I appreciate that, but this is the situation:
I have a program which depends on reading in a handful of files. These files are named like: foo_bar_BAZ.txt where BAZ is the name of the project and not known until run-time. However it will not change for the entire execution of the program.
I want to have an enumerated list of strings which stores all the filenames. So far I have used a sealed class like so:
public sealed class SQLFile
{
private readonly String name;
private readonly String value;
public static readonly SQLFile CrByAuthors = new SQLFile("Changes_CR_By_Authors_%project_name%.txt", "CrByAuthors");
public static readonly SQLFile DocumentCrMetrics = new SQLFile("Changes_Document_CR_Output_%project_name%.txt", "DocumentCrMetrics");
[...]
private SQLFile(String value, String name)
{
this.name = name;
this.value = value;
}
public String ToString(string projectName)
{
return this.value.Replace("%project_name%", projectName);
}
}
As you can see this depends on my providing the project name variable every time I want to access the filename, even though that filename is really constant from the very beginning of run-time till the end.
Is there a more elegant way to handle with this situation?
A simple solution would be to have a static class with a ProjectName property. The value of this property is set during startup of the application. Your class then can use that property.
Add a static property to SQLFile, something like
public sealed class SQLFile
{
//...
private static string sProjectName;
public static string ProjectName
{
get
{
return sProjectName;
}
set
{
//optionally, you could prevent updates with:
//if (string.IsNullOrEmpty(sProjectName))
sProjectName= value;
//else throw Exception("ProjectName was already set!");
}
}
[Edit - I read the code a bit too fast, so this is what I actually meant:]
The purpose of the (poorly named IMHO) method ToString is to return the name of a file corresponding to a certain project name. There is nothing wrong with that, although it may be a responsibility which might belong to a separated class.
You could, for example, refactor the code to express its intention more clearly:
interface ISqlFileNameProvider
{
string SqlFilename { get; }
}
Then have a simple ("poor man's") implementation:
public class SimpleSqlFileNameProvider : ISqlFileNameProvider
{
private readonly string _filename;
public SimpleSqlFileNameProvider(string filename)
{
_filename = filename;
}
public string SqlFilename
{
get { return _filename; }
}
}
And then derive specialized implementation from here:
public class TemplateSqlFileNameProvider : SimpleSqlFileNameProvider
{
public TemplateSqlFileNameProvider(string template, string projectName)
: base(template.Replace("%project_name%", projectName))
{ }
}
public class CrByAuthorsFileNameProvider : TemplateSqlFileNameProvider
{
public CrByAuthorsFileNameProvider(string projectName)
: base("Changes_CR_By_Authors_%project_name%.txt", projectName)
{ }
}
public class DocumentCrMetricsFileNameProvider : TemplateSqlFileNameProvider
{
public DocumentCrMetricsFileNameProvider(string projectName)
: base("Changes_Document_CR_Output_%project_name%.txt", projectName)
{ }
}
First, note that projectName remains the parameter for the constructor of these specialized classes. There are no globals here. Next, even though you've added a bit of plumbing code to your project, it's easier to decouple your classes for simpler testing: you can create a mocked implementation of ISqlFileNameProvider and return whatever you like to test the rest of the functionality without writing to real data files.
I would certainly advise against using a global property. The fact that you can specify the project name as a constructor parameter means that you can easily test that your class behaves the way you want it to. And even though you think that it will change during project lifetime, you can easily encounter a scenario where you temporarily need to switch the project name in runtime. I would advise against using globals.
Here is the design problem in pseudo example:
It is ASP.NET User control (UC) which uses the "Food" object as data source and this object has property FoodType - "Veg" || "Nonveg".
The user control changes UI display depending upon FoodType property. In code-behind class of User Control, some methods have same if/then/else condition: if(Food.FoodType == "Veg")... else ...
Here, I would like use State-like pattern such that code-behind class of User Control will contain two inner/nested classes, i.e. "VegFood" class and "NonvegFood" class. Now, lets say, NonvegFood class will contain its own logic implementation.
But having one interface, two instance classes (as nested) which will be used in this user control only, could be overdesign. In addition to that, UC does not have driver method where I can call related methods in one if block, like they are "DataBound" and "ItemCreated".
Still, is it possible to have State like pattern inside UC class? Probably two instance inner classes inside UC and somehow if I can delegate call to one of these inner class?
class UC : UserControl
{
class VegFood
{
string DisplayName
{
get
{
return "Rice";
}
}
}
class NonvegFood
{
string DisplayName
{
get
{
return "Chicken";
}
}
}
protected string DisplayName
{
get
{
return Instance.DisplayName;
}
}
/*********** MAGIC Property ****************/
private ? Instance
{
get
{
return ?;
}
}
}
I do not think that having three nested classes is not design overkill if it makes the code easier to maintain.
I would suggest an abstract base State class which defines the contract of your states. Each state would inherit from this.
Extended your code sample:
class UC : UserControl
{
protected string DisplayName
{
get
{
return Instance.DisplayName;
}
}
/*********** MAGIC Property ****************/
private FoodState _instance = null;
private FoodState Instance
{
get
{
if (_instance == null)
{
if (FoodType == "Veg")
{
_instance = new VegFood();
}
else
{
_instance = new NonvegFood();
}
}
return _instance;
}
}
abstract class FoodState
{
abstract public string DisplayName {get;}
}
class VegFood : FoodState
{
public string DisplayName
{
get
{
return "Rice";
}
}
}
class NonvegFood : FoodState
{
public string DisplayName
{
get
{
return "Chicken";
}
}
}
}
You probably don't need the protected DisplayName property on the UserControl directly, as Instance.DisplayName could be used directly by the aspx page.