|
|
sorry my bad not intentional
|
|
|
|
|
Assume you have a Class named 'TheClass : here's what you might call a 'normal' ctor:
public class TheClass
{
public string Name { private set; get; }
public List<int> TheClassList { private set; get; }
public TheClass(string name, int init, int inc, int last)
{
Name = name;
TheClassList = new List<int>;
for (int i = init; i < last; i+= inc)
{
TheClassList.Add(i);
}
}
} Now you decide that you want to give the user the option to inject a function into ctor that will modify the generation of values in the 'for loop: so you write a Function:
public Func<int, int> Generator1 = (value) => (value * value); And, you modify the class to pass the Function as a parameter to the ctor, and use it:
public class TheClass
{
public string Name { private set; get; }
public List<int> TheClassList { private set; get; }
public TheClass(string name, int init, int inc, int last, Func<int,int> Generator = null)
{
Name = name;
TheClassList = new List<int>;
if(Generator == null)
{
for (int i = init; i < last; i+= inc)
{
TheClassList.Add(i);
}
}
else
{
for (int i = init; i < last; i+= inc)
{
TheClassList.Add(Generator(i));
}
}
}
} All this is, imho, passable; my question regards what happens when you have many optional types of Functions (or Actions) that you want to be used in the ctor ... so that if you made all of those Funcs (or Actions) part of the ctor parameter list (with 'null as their default value) you'd get a very unwieldy ctor, and/or complex logic in the ctor to decide which functions passed as parameters are invoked.
Here's what I see as the alternatives:
I. define a separate ctor for each possible use case (my current choice).
public TheClass(string name, int init, int inc, int last);
public TheClass(string name, int init, int inc, int last, Func<int,int> Generator1);
public TheClass(string name, int init, int inc, int last, Func<int,int,int, List<int>> Generator2);
II. break-out the code in the ctor in two parts: one that handles everything but the generation of values; put the code for all possible value generation scenarios (and its logic) into a separate 'Initialize function that must be called after the call to the ctor.
III. define the most common (default) initialization method in the ctor, and pass a boolean flag as a parameter to the ctor: if the flag is true, initialization is performed in the ctor, else defer initialization to a call to an 'Initialize function.
Appreciate your thoughts !
«To kill an error's as good a service, sometimes better than, establishing new truth or fact.» Charles Darwin in "Prospero's Precepts"
modified 4-Apr-15 12:58pm.
|
|
|
|
|
Of those, I prefer 1, but they all do too much; a constructor should do very little.
Better to have the constructor receive the List rather than build it. If you do, you might want to make a copy.
A benefit of this technique is that it allows the caller to instantiate your class multiple times with the same data without generating it more than once.
And consider using params :
public TheClass(string name, params int[] List)
{
Name = name;
TheClassList = new List<int> { List };
The caller can use this with the values he wants:
TheClass a = new TheClass ( "A" , 1 , 2 , 3 ) ;
int[] l = new int[] { 1 , 2 , 3 } ;
TheClass b = new TheClass ( "B" , l ) ;
Basically, generating the list is not the constructor's concern.
Having said that... I'm reminded of a Pool<T> class I wrote. Its constructor takes a delegate that constructs one item for the pool and the number of items it should manage. Maybe I should change it to follow my advice above.
[System.ObsoleteAttribute("Don't use this constructor",true)]
public Pool
(
int Capacity
,
Delegate Creator
)
{
this.pool = new T[Capacity];
for (int i = 0; i < this.pool.Length; i++)
{
this.pool[i] = Creator();
}
return;
}
public Pool
(
params T[] Pool
)
{
this.pool = Pool;
return;
}
Modularity, single-responsibility, etc.
modified 4-Apr-15 13:10pm.
|
|
|
|
|
Hi, I appreciate your comments.
For the sake of focusing on what I think is the key issue ... handling the need to have a constructor with a variable number of parameters some of which may be Action or Func ... which are used dynamically in the ctor ... the code I showed here is deliberately as terse and simple as possible.
In the real-world code I am working with (complex, involving Types other than int) the constructors in the library I am creating do need to trigger the construction of lists ... it's a key part of the class' functionality to provide the lists.
It's a personal preference of mine to avoid using 'params unless required, since I feel the use of named variables always contributes to code maintainability; but, of course, you're right in that they are sometimes absolutely necessary because you are dealing with an unpredictably variable number of inputs at run-time. So, I do use them; in fact, I use them in the current library I'm working on.
Your code example is interesting: I don't see you passing the 'i for-loop indexer to the Delegate, which seems strange. The use of 'Delegate there would require you to define a prototype for the Delegate Type like: public delegate T IntDelegate(); to use in the 'ctor.
On the other hand using a Func<T> would require no extra declaration, and, since Func is a Delegate, would be entirely equivalent.
cheers, Bill
«To kill an error's as good a service, sometimes better than, establishing new truth or fact.» Charles Darwin in "Prospero's Precepts"
|
|
|
|
|
BillWoodruff wrote: it's a key part of the class' functionality to provide the lists
That sounds suspicious.
BillWoodruff wrote: you to define a prototype for the Delegate Type
Yes, because I'm old-school, I try not to use new crap when the old crap still works just fine. I just didn't show it.
modified 4-Apr-15 14:36pm.
|
|
|
|
|
If you have a List of Actions to perform, then why are we talking about constructors? Why are you passing in an action, if you can pass an interface?
I'd also like to point out a recent thread[^] on the readability of the constructor
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hi,
I did, indeed, read the thread you refer to in the Lounge, with interest. In fact, my choice to implement multiple constructors ... what I consider best practice now ... one for each case ... is based on believing that improves code maintainability, and readability.
But, I did start this thread with the thought I might learn something new, and I'm certainly willing to change my current preferences
As I just posted to Piebald on this thread: "For the sake of focusing on what I think is the key issue ... handling the need to have a constructor with a variable number of parameters some of which may be Action or Func ... which are used dynamically in the ctor ... the code I showed here [in the original post on this thread] is deliberately as terse and simple as possible."
I can't grok what you are referring to when you say: "pass an interface;" and, I'm curious, how would that work ?
thanks, Bill
«To kill an error's as good a service, sometimes better than, establishing new truth or fact.» Charles Darwin in "Prospero's Precepts"
modified 4-Apr-15 15:09pm.
|
|
|
|
|
BillWoodruff wrote: believing that improves code maintainability, and readability.
I'm with you on that.
|
|
|
|
|
BillWoodruff wrote: I can't grok what you are referring to when you say: "pass an interface;" and,
I'm curious, how would that work ? You can't bind an interface to an action obvious. But if you can pass an Action<T> or Func<T>, then you can pass an object that implements a specific interface. It may require a bit more code, but the advantage of passing merely an interface appears obvious.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hi, Eddy,
I believe I see the point you are making, and I certainly agree with you that passing an instance of #Whatever as an IWhatever is a good way to minimize what "parts" of an instance you expose. I can, and do, use interfaces that spec Funcs; example:
public interface IGenericWhatever<T> where T : struct
{
Func<T, T> SomeFunc1 { set; get; }
Func<T, T, T, List<T>> SomeFunc2 { set; get; }
} For the particular "library for programmers" use case I am developing now, I find it appropriate for the programmer to pass Func definitions in the call to the Class' ctor.
When (if) I publish this library on CP, I'll ask for your review.
thanks, Bill
«To kill an error's as good a service, sometimes better than, establishing new truth or fact.» Charles Darwin in "Prospero's Precepts"
|
|
|
|
|
BillWoodruff wrote: When (if) I publish this library on CP, I'll ask for your review. Looking forward to the article
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Dear Expert,
Is there any solution or Programming method to develop reports without using Crystal reports in C#.
Ahmad
|
|
|
|
|
Well...there's Microsoft Reports[^]
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
You can use SSRS SQL Server Reporting Services with Report Builder. Also I have used ActiveReports several years back and would say it was once of the best experience. At the time I was working on a project replacing Crystal Reports with it.
|
|
|
|
|
I wonder if I can use some classes to develop reports, I need a dynamic report, that user can request same report in multiple design.
|
|
|
|
|
Active Reports would be my recommendation. But I would suggest that you download a free copy and test it before you buy the full version.
http://activereports.grapecity.com[^]
|
|
|
|
|
Have you considered MS-Access?
Rich reporting and a free runtime
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Choke cough spit you are really living up to your sig. Imagine inflicting Access on the poor bastard as a reporting tool, what a nightmare. Not as bad as CR but still has to be one of the lousiest choices.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Mycroft Holmes wrote: Imagine inflicting Access on the poor bastard as a reporting tool, what a nightmare Howso?
I've used it without much problems
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hi,
I have a WinForm C# application with MySQL backend on the server in the company. The application needs to sync with a database on Web.
I thought of adding a is_synced field for the fields needs to be updated but then how can I sync? do I need to SELECT using the first mysql_local_connection and loop through avalable records then connect within the loop to mysql_cloud_connection and do the INSERT?
--> connect to mysql_local_connection
--> SELECT records need to be synced
--> While looping
--------> connect to mysql_cloud_connection
--------> INSERT or UPDATE
--> end loop
is this the best way to do it?
Thanks,
Jassim
Technology News @ www.JassimRahma.com
|
|
|
|
|
If you want the best way to do this, then make sure your data is bound (Use binding[^]) and the Mode for binding is set to TwoWay, also that you're application is capturing every key stroke event and is updating the source by the target data (input). And once user has finished the work, commit the changes back to the database (this would ensure less latency delays).
Then you will be able to ensure (hopefully) that the data is synchronized among your Win Forms application and you MySQL database.
If you do not use data binding, then chances are that you're going handle events, create another background object to hold the data, then inside that class use other interfaces to commit data changes to database and so on. So, better is to use bindings.
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
I'm sorry if I'm wrong section...
I'm doing an application in C#. I have two tables "Audience" and "Schedule" in the database. These tables have the column "Number", which store different values. I need to select from the first table "Audience" in the column "Number" all the values that are not found in the column "Number" table "Schedule" and results displayed in dataGridView. Tell me please how to make a select? how to write a SQL query?
|
|
|
|
|
|
thank you so much!
|
|
|
|
|