I have a class that contains several methods eg.:
class mySqlTool{
private string _values, _table, _condition, _result;
public mySqlTool Select(string values = null){
//this is REQUIRED
_values = string.Format("select {0} ", values);
return this;
}
public mySqlTool Update(string table){
//this is REQUIRED
_table = table;
return this;
}
public mySqlTool Set(string name, String value){
//this is REQUIRED
//handle name and value
return this;
}
public mySqlTool From(string table = null){
//this is REQUIRED
_table = table;
return this;
}
public mySqlTool Where(string condition = null){
//this is OPTIONAL
_condition = condition;
return this;
}
public string Execute(){
//this is REQUIRED
//this is samplecode, of course here is checked if its select or update
//but to keep it short i erased it
statement = string.Format("{0} {1}", _values, _table);
if (!string.IsNullOrEmpty(_condition))
{
statement += string.Format(" where {0}", _condition);
}
//do some with statemen and fill result
return _result;
}
}
now I use this in this chaining way:
MySqlTool t = new MySqlTool();
string result = t.Select("a,b,c").From("x").Where("foo=bar").Execute();
My VS provides me with available methods when I hit DOT (.)
.
My problem is, I want to denie to use some methods before other methods have been used eg:
MySqlTool.Where().Select().From().Execute();
In this case .C()
should not be callable befor .A()
was called. So to clarify whats allowed and whats not, here a small list
//Allowed
t.Select().From().Execute();
t.Select().From().Where().Execute();
t.Update().Set().Set().Set().Where().Where().Where().Execute();
//not Allowed
t.Select().Where().Execute();
t.Select().Select().Select().From().Execute();
t.From()...
t.Where()...
t.Execute()....
I read some about interfaces and also about state but I'm not sure if this is what im searching for.
So my question:
Is this what I want even possible?
If yes, how is this technique called?
General description - see end for specific comments
Not within the same class, no. How would the compiler know what you'd already called? (Imagine you had a method with a parameter of type
Test
- what methods should be available to call on that?) The type system decides what's valid and what's not - so if there are different sets of valid operations, that suggests different types.What you can do is have different types representing the different states, which will only include the appropriate methods for state transitions. So you could have something like this:
Then you can use:
... but your invalid cases wouldn't compile.
It works, but it's pretty ugly. Without knowing what the methods are meant to achieve, it's hard to suggest anything else - but in many cases a single method with optional parameters may be better, or possibly a builder pattern.
An alternative is to use a single class and validate the calls at execution time instead, of at compile time. That's less helpful when coding, but avoids having a huge mess of types.
Yet another alternative would be to have a single class - and create a single instance - but use interfaces to represent the state. Your class would implement all the interfaces, so it could still just return
this
:Then you'd have:
But this feels pretty wrong to me. I'd expect the
A
,B
andC
methods to be effectively changing state in some way - so having separate types would indicate which state is available. In the first example, aTest0
definitely doesn't have the state provided by theA
call, but aTest1
does... and aTest2
instance has state provided byA
andB
, and possiblyC
.Specific example
For the specific example given, I'd probably just make the constructor handle the required information (the table name) and use properties/indexers for the rest. I'd probably separate out a query command from updates:
And:
In each case there'd be an
Execute
method returning the appropriate results.