Dynamically select element based on function parameter - c#

I am creating an Automation Testing framework, and I came up with this function:
public void DoClick(string selectType, string selector)
{
switch (selectType)
{
case "ClassName":
driver.FindElement(By.ClassName(selector)).Click();
break;
case "CssSelector":
driver.FindElement(By.CssSelector(selector)).Click();
break;
case "Id":
driver.FindElement(By.Id(selector)).Click();
break;
}
}
I want to replace the "By..." with something like By[selectType], in order to write a single line of code, instead of the whole switch case. How can I achieve that?

It's pretty simple. There's really no need to do this. Why wrap a one-liner inside a function?
public void DoClick(By locator)
{
driver.FindElement(locator).Click();
}

Related

Unity Multi Objects with same scripts issue

I have like 20 objects with the same script. And the problem that when I want to set a value for every each object only one respond to the script. here is the objects main script
[SerializeField]
private int Id = 0;
public void SetId(int num)
{
Id = num;
}
public int ReturnId()
{
return Id;
}
And here where they are called:
private void DeterminedWallColor()
{
for (int i = 0; i < _colorType.Length; i++)
{
switch (_colorType[i])
{
case 1:
_wId.SetId(_colorType[i]);
break;
case 2:
_wId.SetId(_colorType[i]);
break;
case 3:
_wId.SetId(_colorType[i]);
break;
case 4:
_wId.SetId(_colorType[i]);
break;
}
}
}
The problem is you shouldn't be using a switch statement. The code you have right now will always match the first case because all the cases below it are the same as the first case and will always be the same as the firsts case because it is the same code/expression in all the cases you are checking for.
Also since you want to set a value for each gameObject(assuming you want to set the Id), you would need to loop thru all the gameObjects first, and then set each _colorType per gameObject, according to what you want/need. (I cannot provide code example because your question was vague, and you did not provide context for your code examples such as "_colorType". I cannot tell where that variable came from since you did not provide the variable implementation)

How to programically change the function name I call

I am trying to call a function based on information from a combobox. The user will change the combobox and in doing so we call a function according to the data in the combobox text joined with a fixed text. I am trying to do this so every time we get a new version I just add a folder and do not have to go into the code to add new function names like in a case statement.
The combobox would have text as
v6.1
v6.4
v7.2
v8.6
and so on
The function I want to call is named Getinfo_ with the addition of the text from the combobox with the . replaced with _ e.g. I would choose v6.1 from combobox and in doing so I would call function called Getinfo_v6_1
After a lot of thinking searching and trying I have got close but not close enough yet. I think I need to use Reflection (maybe not) and
private void cmbobx_version_SelectedIndexChanged(object sender, EventArgs e)
{
Type t = this.GetType(); //need to get the type
MethodInfo method = t.GetMethod("Getinfo" + cmbobx_version.Text.Replace('.', '_')); //put together function name
method.Invoke(this, new object[] {Fridge, "Order" }); //call function with parameters
}
Unfortunately this stops at invoke saying the method is NULL, I do not understand why this is so apart from maybe I totally misunderstand what I am doing.
The function I want to call would look a bit like the following
public void Getinfo_v6_1(ComboBox inFocusComboBox, string action)
{
switch (inFocusComboBox.Text)
{
case "Red": Price = 11254; break;
case "Blue": Price = 11278; break;
case "Green": Price = 11354; break;
}
}
public void Getinfo_v6_4(ComboBox inFocusComboBox, string action)
{
switch (inFocusComboBox.Text)
{
case "Red": Price = 254; break;
case "Blue": Price = 278; break;
case "Green": Price = 354; break;
}
}
All help greatly appreciated even if you have a better way of doing what I need to do.
You should read about design patterns for example you could create polymorphic items that implement your function using for example the template design pattern. Try to avoid reflection as it is ‘slow’ and not type safe.
Thanks to Ĵošħ Williard I had indeed missed out the underscore and when working with it I had not noticed as I also do a text replace from . to _ and thought it was all correct. Even when debugging I did not see it, often we cannot see the obvious which is why a second opinion of those wiser than me is always good.
The working code is now as follows.
private void cmbobx_version_SelectedIndexChanged(object sender, EventArgs e)
{
Type t = this.GetType(); //need to get the type
MethodInfo method = t.GetMethod("Getinfo_" + cmbobx_version.Text.Replace('.', '_')); //put together function name
method.Invoke(this, new object[] {Fridge, "Order" }); //call function with parameters
}
Please do be careful as the functions will have no references but it will compile and will work. It all works at run-time when you call the correct function.

Using switch case with thread safe enum

If I have an Enum as follows:
private object myEnumValLock = new object();
private MyEnum _myEnumVal;
public MyEnum MyEnumVal
{
get
{
lock(this.myEnumValLock)
{
return this._myEnumVal;
}
}
set
{
lock(this.myEnumValLock)
{
if (value != this._myEnumVal)
{
this.HandleNewMyEnumVal(this._myEnumVal, value);
this._myEnumVal = value;
}
}
}
}
When using switch case, can I directly use the property like this:
private void MyFunc()
{
switch (this.MyEnumVal)
{
case MyEnum.First:
// Do Something
break;
case MyEnum.Second:
// Do Something
break;
}
}
Or should I read it first and then use switch on the read value like this:
private void MyFunc()
{
var myEnumVal = this.MyEnumVal;
switch (myEnumVal)
{
case MyEnum.First:
// Do Something
break;
case MyEnum.Second:
// Do Something
break;
}
}
If using if ... else as in this question, I'd need to read the value first. Is it the same case with switch statement? What is the behaviour of the switch statement? Does it read the value at every case statement or reads only once at the beginning?
As #mjwills suggested, I put a breakpoint in the getter and it got hit only once at the beginning of the switch statement. I can't find any specific reference where it says the switch statement reads the value only once (please comment if you find the reference). But the breakpoint does prove it.
So, although you need to have read the value beforehand in case of if ... else, in case of the switch statement, you don't need to.

Use a "null" switch statement to determine if a range of TextBoxes are null, instead of using if-else statements

At the moment, I am trying to write a method that has inside it a switch statement which uses as the "trigger" the reserved word null. This is because I want all the TextBoxes, in this switch statement to be tested for the state of being null, and if they are, a MessageDialog (which I've coded for each box) will appear saying that 'You cannot leave "insert name of TextBox here", blank. You must enter text'
In short, is it possible to use a switch statement to test if a bunch of TextBoxes are null, rather than using a whole sequence of (unwieldy) if-else statements? If so, how? (please)
I should add that I've been at this problem for the last hour and a half, with no success.
Any help is gratefully accepted.
If you specifically want to use a Switch:
Make them into a List or an Array, if it is not that already.
List<string> TextBoxCollection = new List<string>();
TextBoxCollection.Add(yourTextBoxStringValue); //Do this for each of the boxes.
Then just iterate through the TextBoxCollection.
foreach (string textContent in TextBoxCollection)
{
switch (textContent)
{
case null:
{
//Do the message error here.
break;
}
case "otherRequirement":
{
//Do other stuff here.
break;
}
case "anotherRequirement":
case "oneMoreRequirement":
{
//Do different things here, maybe?
break;
}
}
}
This will iterate through the collection, and then test each string from it.
I would not recommend doing this, unless all the text boxes' values have to be validated for multiple conditions, all the same, in which case this will look more tidy than an If Else for each string value.
If you want a quick one line solution to check this for each one, you can just use:
if (string.IsNullOrWhiteSpace(yourTextBox.Text)) { //Throw error here. }
You can do the following:
Create a method, which will loop over Controls recursively:
public static void ForAllControls(this Control parent, Action<Control> action)
{
foreach (Control c in parent.Controls)
{
action(c);
ForAllControls(c, action);
}
}
Create a method, which will validate the TextBox:
public void validateTextBoxes(Control c)
{
if (c.GetType() == typeof(TextBox))
if(TextBox.Text == "") MessageBox.Show("insert name of TextBox here")
}
Call the method, like this:
this.ForAllControls(c => {
if (c.GetType() == typeof(TextBox)) validateTextBoxes(c);
});
Or use ErrorProvider.SetError();
This may not be using switch but it will save you some lines.
public static void IsTxtNull(Textbox xTxt, string msg)
{
if(string.IsNullOrEmpty(xTxt.Text)
MessageBox.Show(msg);
}
Then call it like this
IsTxtNull(YourTxtBox1,"Message for YourTxtBox1");
IsTxtNull(YourTxtBox2,"Message for YourTxtBox2");
IsTxtNull(YourTxtBox3,"Message for YourTxtBox3");
etc...

c# class - make function or method call and pass control

I'm not sure if my title is really correct. I've looked around and searched but not found anything so please forgive me if my problem has been answered already.
What I would like to do is call a function but not have to come back to the calling line of code. e.g
public static void temp(obj) {
switch (obj.id) {
case "1" :
if(blah) {
obj.id = "2";
temp(obj);
}
break;
case "2" :
obj.response = "done";
break;
}
}
so basically I dont want to eventually come back to my temp(obj) in the first case and fully pass control. Does this make sense, is it even possible and my architecture is all wrong?
Thank you for your time.
Let me see if I understand the question:
You've got a function Foo(), which calls function Bar(). (I wanted to remove the recursion you had in your example for simplicity, please correct me if that was important.) When function Bar() returns, you want control to pass not back to Foo(), but to Foo's caller?
This is probably possible in lower-level languages, like C, by hacking the stack and not placing Foo()'s return address there, so that when Bar() tried to return, it would jump to Foo's caller instead.
However, in C#, no. The call stack is a stack, and control will pass back in order. The only thing you can do would be to put a return statement after each call to Bar().
Edit:
"recursive calls without them being recursive"
How about this:
bool doItAgain = true;
while(doItAgain)
{
doItAgain = false;
// process, with your switch statement or whatever.
if(...)
{
doItAgain = true;
continue; // if necessary, skip any code after this statement. May not be necessary if you have things set up right.
}
}
If this were C++, you could eliminate the break and let the case "1" fall through, but this is not allowed in C# switch statements.
public static void temp(obj) {
if (obj.id == "1") {
obj.id = "2";
temp(obj);
}
if (obj.id == "2")
obj.response = "done";
}
Do you need the recursive call? This code retains your recursive call and sets obj.response to "done" after changing obj.id to "2". However, obj.response is set twice because of the recursive call. What are you trying to do?
I'm not sure what you exactly intend, but it sounds like a callback to me. Here is one possible example:
void DoSome()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { RunMe(); ReturnTo(); }));
}
void RunMe() { }
void ReturnTo() { }
You start in DoSome() and continue, when RunMe is finished ReturnMe is called.

Categories

Resources