c# restrict methods to other methods - c#

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
Is this what I want even possible?
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:
class Test0 // Initial state
{
public Test1 A() { ... }
}
class Test1 // After calling A
{
public Test2 B() { ... }
}
class Test2 // After calling B
{
// This returns the same type, so you can call B multiple times
public Test2 B() { ... }
// This returns the same type, so you can call C multiple times
public Test2 C() { ... }
public string DoSomething() { ... }
}
Then you can use:
Test0 t = new Test0();
string x1 = t.A().B().DoSome();
string x2 = t.A().B().C().DoSome();
string x3 = t.A().B().B().B().C().C().C().DoSome();
... 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:
interface IStart
{
IMiddle A();
}
interface IMiddle
{
IFinal B();
}
interface IFinal
{
IFinal B();
IFinal C();
string DoSomething();
}
class Test : IStart, IMiddle, IFinal
{
public IMiddle A(string x = null) { return this; }
public IFinal B(string x = null) { return this; }
public IFinal C(string x = null) { return this; }
public string DoSomethign { ... }
}
Then you'd have:
IStart t = new Test();
string x1 = t.A().B().DoSome();
string x2 = t.A().B().C().DoSome();
string x3 = t.A().B().B().B().C().C().C().DoSome();
But this feels pretty wrong to me. I'd expect the A, B and C methods to be effectively changing state in some way - so having separate types would indicate which state is available. In the first example, a Test0 definitely doesn't have the state provided by the A call, but a Test1 does... and a Test2 instance has state provided by A and B, and possibly C.
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:
SqlQuery query = new SqlQuery("table")
{
Columns = { "a", "b", "c" },
Where = { "foo=bar" } // Not sure how you're parameterizing these
};
And:
SqlUpdate update = new SqlUpdate("table")
{
// Which columns to update with which values
["a"] = 10,
["b"] = 20,
Where = { "foo=bar" } // Not sure how you're parameterizing these
};
In each case there'd be an Execute method returning the appropriate results.

Related

How does multiple method calls in an if-statement work?

I am relatively new in C#.
I am trying to understand how the flowing bit of code is working.
public static int Method3()
{
//some code
If(Class1.Method1(int Variable1).Method2(Class3 Variable2))
{
//even more code
}
//some code
}
OK, now a bit of context.
This if-statement is in Method3 and Method3 is the Class Class1.
Method1 takes an Int value and returns NULL or an Class Class2.
Method2 takes a Class lets call it Class3 and it returns true or false.
So I understand for the if-statement to be valid the condition must return true or false.
Which will come from the Method2 from my understanding.
But what is Method1 doing here?
What happens with the output of Method1?
Does it have any influence to the condition?
I hope you guys can understand what I mean.
If not please ask.
It would be far easier to understand if you get an example with more meaninful names.
Warning: This code and the one in your question is vulnerable to NullReferenceException. If GetClient returns null, you will have an exception.
For example:
public static bool SellingExample1()
{
int clientId = 21;
// Possible NullReferenceException
if(Shop.GetClient(clientId).OwesMoney())
{
// Send warning email to sales manager
}
// Do selling logic
}
public static bool SellingExample2()
{
int clientId = 21;
Client clientToSell = Shop.GetClient(clientId);
if (clientToSell == null) return false; // Check to avoid NullReferenceException before calling methods on a null object.
bool clientOwesMoney = clientToSell.OwesMoney();
if(clientOwesMoney)
{
// Send warning email to sales manager
}
// Do selling logic
}
public class Shop
{
public static Client GetClient(int clientId)
{
// Look the database and return the client
}
}
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public bool OwesMoney()
{
// Return true if there are unpaid bills
}
}
A method doesn't take a class. It takes an instance of a class.
Think of a class as a description of a thing and an instance as a specific thing of that kind, e.g. Cat might be a class where "Tom the cat" might be an instance.
The picture is a little more complex because methods can be static meaning they belong with the class or not, meaning they belong with the instance. In the following, I'll assume you are dealing with static methods because the method in your example is static.
Because you are chaining method calls, I assume Method1 returns something (an object instance) you can call Method2 on.
Now let's look at how your code might be modified given that understanding:
public static int Method3()
{
//some code
int Variable1 = 42;
Class3 Variable2 = new Class3();
if(Class1.Method1(Variable1).Method2(Variable2))
{
//even more code
}
//some code
}

C# referencing a methods variables from another method [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Sometimes it happens that I want to use a lot of Method As variables in Method B.
Usually its quite a pain to pass all the variables to this method, especially if I have to do this a lot of times (but cannot simply copy paste, because some things change) or am just to lazy.
Is there such a thing like a "inner Method"? Or some concept to handle this in an easy way?
What I want to do:
public void A()
{
int a = 4;
string b = "Hello World";
B(ref vals);
//Or like so
C(ref current);
}
public void B(ref AllValues)
{
a = 3;
...
}
public void C(ref MethodThatSharesAllValues method)
{
method.a = 3;
...
}
If they all are in the same class
You can configure them as class variables:
public class MyClass{
//set this as private/protected/public or nothing and you can also set a default value
int a;
public void A()
{
a = 4;
string b = "Hello World";
B();
C();
}
public void B()
{
a = 3;
...
}
public void C()
{
a = 3;
...
}
}
Elseway
public static class MyClassA{
public static int a = 0;
public static void MethodA(){
this.a = 3;
}
}
now from method B you can access MyClassA
int myExValueA = MyClassA.a;
Elseway you gotta pass them as parameters
hope this helps
You can create a class which will hold your parameters and then pass only an instance of this class
public void metA(Parameters input)
{
input.a = 5;
input.c = "hello";
metB(input);
}
public void metB(Parameters input)
{
input.b = 10;
}
public class Parameters
{
public int a;
public int b;
public string c;
}
You can declare the variables static in a class header and use them as you like, private if are in the same class, protected for child classes, internal or public else. Or box the variables in a class like this:
public class Foo
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
If passed variables are the same type you can use data structure like int[] or string[] or List<int> or List<string> and pass them without ref but this has the disadvantage that more than often you would not use all varibales from the structure as it is also the case with the class boxing variant.
Something like the following:
public void foo() {
int a = 10;
// ...
}
public void foo_bar() {
// "a" is not in scope for foo_bar, so this won't compile
a = 20;
// ...
}
would definitely be invalid. I don't think that this was what you were driving at in your question though.
You can do something somewhat similar to what you ask for using closures but they're a bit tricky to work with. Basically, something like this would be valid (and I'm not sitting in front of an IDE so forgive me if the syntax is a little off):
Func<int> GetCounter() {
int count = 0;
// This will capture the count variable from its context
Func<int> method = () => ++count;
return method;
}
While a fair number of languages (including some versions of C++ now I guess) have closures (or some similar variant), there seems to be little consistency in exactly how they work across languages (e.g. on whether the "count" variable should be immutable once it's captured) so it's important to check the documentation for the language you're using (in this case, C#) to understand exactly how they work.
In terms of the first code sample I provide, I doubt that that's what you were asking about, but just as a brief digression you probably wouldn't really want it to be the allowable anyway (and again I suspect that this isn't the syntax/semantics you're asking about) as it would quickly lead to unexpected/undefined behavior. For example:
If you have a local variable a that's initialized in Foo() and you refer to it in Foo_Bar() before you run Foo(), what should its value be?
If you run Foo() to initialize the variable, edit the variable in Foo_Bar(), and then run Foo() again, should you re-initialize the variable or allow it to remain what Foo_Bar() set it to?
Is it safe to garbage collect a local variable after the method call completes, or might it be referred to again?
See the following:
public class SomeObject
{
public int SomeProperty { get; set; } = 6;
// ...
}
public class SomeOtherObject
{
// ..
}
void foo() {
// What is the content of "a" before foo() runs?
object a = new SomeObject();
// Which "a" should this refer to - the one in foo() or the one in foo_bar()?
// Also, is this a valid cast given that we haven't specified that SomeOtherObject can be cast to SomeObject?
var b = (SomeObject)a;
// If we run foo() again, should "b" retain the value of SetProperty or set it back to the initial value (6)?
b.SetProperty = 10;
// ...
// Is it safe to garbage collect "a" at this point (or will foo_bar refer to it)?
}
void foo_bar() {
object a = new SomeOtherObject();
// ...
}

Generate code for creating an object with current values

I have this scenario, which I think must be pretty common:
class Parameter
{
public int someInt;
private decimal someDecimal;
public SubParameter subParameter;
}
class SubParameter
{
public string someString { get; set; }
}
I have a breakpoint at a call to a method that takes a Parameter as a parameter. I want to write a unit test where I call this method with the same exact value (a copy of the Parameter object "tree").
It is very tedious in this case to write the many lines declaring and initializing all the fields and properties of the class, which themselves might be non-primitive etc.
It would be nice if I could just right-click on the parameter variable and then have code auto-generated to create such an object.
So if at my breakpoint, my Parameter object has the value
Parameter parameter = new Parameter
{
someInt = 42,
someDecimal = 42.42m,
subParameter = new SubParameter { someString = "42" }
};
well, then that code would be generated. I could then use the generated code for my unit test.
Does such a thing exist?
Edit:
I guess I have been unclear. I know perfectly well how to write the code myself by hand.
What I want is that when I am hitting a breakpoint and watching a complex variable (or any variable for that matter), I want to be able to say: Generate code for me that creates a clone of this variable. I would use the generated code for my unit test.
Does such a tool exist?
Just create a helper method to create the parameter for you:
public void CreateParameter()
{
return new Parameter
{
someInt = 42,
someDecimal = 42.42m,
subParameter = new SubParameter { someString = "42" }
};
}
Sample use
[TestMethod]
public void MyTest()
{
SomeClass.MethodBeingTested(CreateParameter());
}
If you want to have a specific parameter value then modify the returned parameter or provide an overload which allows you to supply that value:
[TestMethod]
public void MyTest()
{
Parameter parameter = CreateParameter();
parameter.someInt = 23;
SomeClass.MethodBeingTested(parameter);
}
I usually have my CreateParameter populate the parameter with random values to reduce the possibility that the unit test happens to pass "by chance" for certain values, but will fail for others.
You can use TestInitialize for initialize test methods:
[TestClass]
public class UnitTest1
{
Parameter _parameter = null;
[TestInitialize]
public void Initialize()
{
_parameter = new Parameter
{
someInt = 42,
someDecimal = 42.42m,
subParameter = new SubParameter { someString = "42" }
};
}
[TestCleanup]
public void Cleanup()
{
_parameter = null;
}
[TestMethod]
public void MyTest1()
{
// test _parameter
}
[TestMethod]
public void MyTest2()
{
// test _parameter
}
}

How to implement a cache attribute?

How can I implement a CacheAttribute so I can have the same logic for all properties in one place?
I am doing this to cache
[TestClass]
public class All
{
public string N
{
get
{
var value =
MemoryCache.Default.Get("Website.Tests.All.N") as string;
if (value != null)
{
return value;
}
value = DateTime.Now.ToString("HH:mm:ss.ffff");
MemoryCache.Default.Add("Website.Tests.All.N", value,
new CacheItemPolicy
{
AbsoluteExpiration =
new DateTimeOffset(DateTime.Now.AddSeconds(5))
});
return value;
}
}
[TestMethod]
public void Extension()
{
var start = N;
Thread.Sleep(1000);
var end = N;
Assert.AreEqual(start, end);
}
}
And I want to use this instead
[TestClass]
public class All
{
[Cache(Duration=5000)]
public string N
{
get
{
return DateTime.Now.ToString("HH:mm:ss.ffff");
}
}
[TestMethod]
public void Extension()
{
var start = N;
Thread.Sleep(1000);
var end = N;
Assert.AreEqual(start, end);
}
}
Is there a way to make this syntax sugar?
It seems you want to "take over" the get method for the property so as to inspect a cache first before returning the "actual" value from your property. Since there is no way to perform property interception on an ad-hoc basis, you'll have to plan ahead for this facility.
One approach would be to use interfaces and write your classes to the interface. For example,
public interface IAll
{
string N { get; set; }
}
Now you can use proxies to create a wrapper around the original instance of All that also implements this interface. Furthermore, since you're fully in charge of the property now, you can check the cache whenever the getter is called. Since you'll have the PropertyInfo/MethodInfo at your disposal, you should have no trouble generating a unique key per property.
So, whenever you would instantiate an instance of All, you also instantiate this proxy, passing it the instance of All. All subsequent usages of that instance of All should instead be passed the proxy. Like any class factory implementation, this requires you to forgo use of the new operator.
Alternatively, you can use virtual methods instead of interfaces.

How to use Comparer for a HashSet

As a result of another question I asked here I want to use a HashSet for my objects
I will create objects containing a string and a reference to its owner.
public class Synonym
{
private string name;
private Stock owner;
public Stock(string NameSynonym, Stock stock)
{
name=NameSynonym;
owner=stock
}
// [+ 'get' for 'name' and 'owner']
}
I understand I need a comparer , but never used it before. Should I create a separate class? like:
public class SynonymComparer : IComparer<Synonym>
{
public int Compare(Synonym One, Synonym Two)
{ // Should I test if 'One == null' or 'Two == null' ????
return String.Compare(One.Name, Two.Name, true); // Caseinsesitive
}
}
I prefer to have a function (or nested class [maybe a singleton?] if required) being PART of class Synonym instead of another (independent) class. Is this possible?
About usage:
As i never used this kind of thing before I suppose I must write a Find(string NameSynonym) function inside class Synonym, but how should I do that?
public class SynonymManager
{
private HashSet<SynonymComparer<Synonym>> ListOfSynonyms;
public SynonymManager()
{
ListOfSymnonyms = new HashSet<SynonymComparer<Synonym>>();
}
public void SomeFunction()
{ // Just a function to add 2 sysnonyms to 1 stock
Stock stock = GetStock("General Motors");
Synonym otherName = new Synonym("GM", stock);
ListOfSynonyms.Add(otherName);
Synonym otherName = new Synonym("Gen. Motors", stock);
ListOfSynonyms.Add(otherName);
}
public Synonym Find(string NameSynomym)
{
return ListOfSynonyms.??????(NameSynonym);
}
}
In the code above I don't know how to implement the 'Find' method. How should i do that?
Any help will be appreciated
(PS If my ideas about how it should be implemented are completely wrong let me know and tell me how to implement)
A HashSet doesn't need a IComparer<T> - it needs an IEqualityComparer<T>, such as
public class SynonymComparer : IEqualityComparer<Synonym>
{
public bool Equals(Synonym one, Synonym two)
{
// Adjust according to requirements.
return StringComparer.InvariantCultureIgnoreCase
.Equals(one.Name, two.Name);
}
public int GetHashCode(Synonym item)
{
return StringComparer.InvariantCultureIgnoreCase
.GetHashCode(item.Name);
}
}
However, your current code only compiles because you're creating a set of comparers rather than a set of synonyms.
Furthermore, I don't think you really want a set at all. It seems to me that you want a dictionary or a lookup so that you can find the synonyms for a given name:
public class SynonymManager
{
private readonly IDictionary<string, Synonym> synonyms = new
Dictionary<string, Synonym>();
private void Add(Synonym synonym)
{
// This will overwrite any existing synonym with the same name.
synonyms[synonym.Name] = synonym;
}
public void SomeFunction()
{
// Just a function to add 2 synonyms to 1 stock.
Stock stock = GetStock("General Motors");
Synonym otherName = new Synonym("GM", stock);
Add(otherName);
ListOfSynonyms.Add(otherName);
otherName = new Synonym("Gen. Motors", stock);
Add(otherName);
}
public Synonym Find(string nameSynonym)
{
// This will throw an exception if you don't have
// a synonym of the right name. Do you want that?
return synonyms[nameSynonym];
}
}
Note that there are some questions in the code above, about how you want it to behave in various cases. You need to work out exactly what you want it to do.
EDIT: If you want to be able to store multiple stocks for a single synonym, you effectively want a Lookup<string, Stock> - but that's immutable. You're probably best storing a Dictionary<string, List<Stock>>; a list of stocks for each string.
In terms of not throwing an error from Find, you should look at Dictionary.TryGetValue which doesn't throw an exception if the key isn't found (and also returns whether or not the key was found); the mapped value is "returned" in an out parameter.
Wouldn't it be more reasonable to scrap the Synonym class entirely and have list of synonyms to be a Dictonary (or, if there is such a thing, HashDictionary) of strings?
(I'm not very familiar with C# types, but I hope this conveys general idea)
The answer I recommend (edited, now respects the case):
IDictionary<string, Stock>> ListOfSynonyms = new Dictionary<string,Stock>>();
IDictionary<string, string>> ListOfSynForms = new Dictionary<string,string>>();
class Stock
{
...
Stock addSynonym(String syn)
{
ListOfSynForms[syn.ToUpper()] = syn;
return ListOfSynonyms[syn.ToUpper()] = this;
}
Array findSynonyms()
{
return ListOfSynonyms.findKeysFromValue(this).map(x => ListOfSynForms[x]);
}
}
...
GetStock("General Motors").addSynonym('GM').addSynonym('Gen. Motors');
...
try
{
... ListOfSynonyms[synonym].name ...
}
catch (OutOfBounds e)
{
...
}
...
// output everything that is synonymous to GM. This is mix of C# and Python
... GetStock('General Motors').findSynonyms()
// test if there is a synonym
if (input in ListOfSynonyms)
{
...
}
You can always use LINQ to do the lookup:
public Synonym Find(string NameSynomym)
{
return ListOfSynonyms.SingleOrDefault(x => x.Name == NameSynomym);
}
But, have you considered using a Dictionary instead, I believe it is better suited for extracting single members, and you can still guarantee that there are no duplicates based on the key you choose.
I am not sure that lookup time is of SingleOrDefault, but I am pretty sure it is linear (O(n)), so if lookup time is important to you, a Dictionary will provide you with O(1) lookup time.

Categories

Resources