In the below code, I am repeating the same code twice except one change. If there is a way to write the same in single line then it would be great.
The only changes I made is Obsc and zp based on the if..else statement.
var zp = __Services.GetValue("Z", Order.Code);
var St="";
if(sp.Label != null)
{
var Obsc = _Services.GetValue("Z", sp.Label);
St= string.Format(Obsc, .......,userProfile.DisplayName());
}
else
{
St = string.Format(zp, ......., userProfile.DisplayName());
}
Are you happy with something like this?
var code = sp.Label is null
? Order.Code
: sp.Label;
var zpOrObsc = service.GetValue("Z", code); // please use a valid variable name
var st = string.Format(zpOrObsc, ......, userProfile.DisplayName());
St = string.Format(_Services.GetValue("Z", sp.Label ?? Order.Code), ......., userProfile.DisplayName());
Make a variable to determine which parameter value you want to call GetValue with. You only need to call GetValue once and string.Format once.
var whateverTheSecondParamForGetValueIs = Order.Code;
if (sp.Label != null) {
whateverTheSecondParamForGetValueIs = sp.Label;
}
var zp = _Services.GetValue("Z", Order.Code);
var St = string.Format(zp, ......., userProfile.DisplayName());
No, this isn't a "single line", but I don't see the appeal in that. To me, this is much more readable than any ternary operator.
I'm also going to say that these variable names need quite an improvement. They don't convey any meaning.
The ternary (*) operator, also known as the "conditional operator" is basically a short-hand for "if then else " and is written like so:
result = condition ? trueValue : falseValue;
It is not comparable to an actual if ... else ... statement as it is an expression and must provide a value.
See its documentation in the C# language reference for full details: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator.
*) So called because it is the only operator that takes 3 arguments. Compare with "binary operator" and "unary operator".
Related
is it possible to evaluate a single string in c#. The string itself will only be determined during run-time and therefore cannot be set before hand. please see example:
var a = "a == b";
if(a){
//do something
}
EDITED:
This is a actual example of what i would like computed:
var evaluationToBeDone = "MUST_CE_I = \"MUST_CE_I\"";
if(evaluationToBeDone){
// i will do something if the above is true
}
I see what you're trying to do, but the approach doesn't make sense. When you make a variable into an object, the program only reads it as letters, not any logic inside of the object. Try doing this:
var a = "MUST_CE_I"
var b = "\"MUST_CE_I\""
if (a == b)
{
do stuff
}
I assume you want your second string to have the " " quotes, so this should give you what you need. Even though the if statement will always return false since the two variables are not equal.
Lets say i have
int a = 1;
int b = 2;
string exp = "b > a";
and i want to evaluate the string expression with those variables
if(exp.SomeKindOfParseOrCast())
{
//here be magic
}
Is it possible in any simple way?
Nope, not in C# - these are parameter names, and thus are compile time values, and this expression parsing you are describing is done in runtime - the computer doesn't know the name of the parameters while it's being evaluated. Instead, you could do something a little more strict, like an expression parser - implement your own way to parse string expressions.
Very very simplified:
if(exp.Equals("b > a"))
{
if(b>a)
// do what you do if b is bigger than a
else
// do what you do with a wrong expression
}
else if (exp.Equals("a > b")
{
if(a>b)
// do what you do if a is bigger than b
else
// do what you do with a wrong expression
}
else if (exp.Equals("a = b")
{
if(a==b)
// do what you do if a is equal to b
else
// do what you do with a wrong expression
}
else
// do what you do with a badly formatted expression
if you would like to take this a step forward, you can cut spaces, make sure the expression is lowercase, etc. - there's many examples around, I personally like this one.
Is it possible in any simple way?
No, in C# this is not possible in a simple way like it were in languages such as JavaScript with its eval function. Anyway, you'd have to provide bindings of in-expression parameters to actual values.
You can use Roslyn.
Here is an example of how to compile and run your own code in runtime.
Disclaimer: I'm the owner of the project Eval Expression.NET
This library is very easy to use and allow to evaluate and compile almost all the C# language.
// For single evaluation
var value1 = Eval.Execute<bool>("b > a", new { a = 1, b = 2 });
// For many evaluation
var compiled = Eval.Compile<Func<int, int, bool>>("b > a", "a", "b");
var value2 = compiled(1, 2);
I am converting code from Java to C#, but having issues figuring out some keyword equivalence. I have looked over the web and can't find anything. Updated added number 3.
1) Does anyone know what C# uses for charAt()? Below is how I am trying to use it.
curr = tokens[i].charAt(0);
2) Also having issues converting isEmpty() to C# syntax.
if (par.isEmpty())
3) How should I convert this:
op2 = compute.pop().intValue();
Thanks!
1) Strings can have their characters accessed by using the [] operator:
curr = (tokens[i])[0];
2) IsEmpty becomes String.IsNullOrEmpty or String.IsNullOrWhiteSpace depending on what you want (the second is only available in .NET 4+ as well).
3) From what research I could find, it looks like intValue deals with boxing/unboxing. If you stick with working with ints, you shouldn't need to worry about that in C#. "Pop" will work the same if you have a Stack collection. Hopefully that gives you enough to convert the line.
1) In C# a string is also an array of characters.So you can access a character using the indexer:
curr = tokens[i][0]
2) You can compare your string with string.Empty or use String.IsNullOrEmpty method to check whether a string is empty or not:
if( par == string.Empty )
OR:
if( string.IsNullOrEmpty(par) );
Assuming tokens[i] is a string, treat the string as an array of characters:
var firstCharacter = tokens[i][0];
Assuming par is also a string, the string.IsNullOrEmpty() method can help you test whether or not a particular string is empty:
if (string.IsNullOrEmpty(par))
{
}
If par is a Stack<String> as you've indicated, then you could test whether it was empty (has no elements) with a simple bit of LINQ:
if (!par.Any())
{
// par has no elements
}
Alternatively, you could use the Count property in the Stack class:
if (par.Count == 0)
{
// par has no elements
}
A different approach:
1) You can use curr = tokens[i].ElementAt(0); This will return the same result as charAt(0)
2) if( string.IsNullOrEmpty(par) ); will do the job.
I have a scenario in which I am saving my "if" conditions in database as a string. For example:
String condition = "(([age] >= 28) && ([nationality] == 'US'))";
OR
String condition = "([age] >= 28)";
Now, I want to evaluate that the user has input the condition syntactically correct. These are example of incorrect syntax:
String condition = "(([age] >= 28) && ([nationality] == 'US')"; //Missed ')' bracket
String condition = "[age] >= 28)"; //Missed Opening bracket '('
Like we have in Evaluate Query Expression. Might be Expression tress can be helpful. But how? Need help in this regard.
Take a look at NCalc. It's a framework for evaluating mathematical expressions.
When the expression has a syntax error, the evaluation will throw an EvaluationException.
try
{
new Expression("(3 + 2").Evaluate();
}
catch(EvaluationException e)
{
Console.WriteLine("Error catched: " + e.Message);
}
Though, you can also detect syntax errors before the evaluation by using the HasErrors() method.
Expression e = new Expression("a + b * (");
if(e.HasErrors())
{
Console.WriteLine(e.Error);
}
Visual studio doesn't really know what the strings represent so to my knowledge there is no parsing done within the strings themselves.
Typically when programming with C# and using sql, you'd try to do as much of the calculations as possible in C# itself (if it's feasible select the whole table then deal with the result using C#).
If the database is really slow which is quite often the case, it may be useful writing a SQL Builder class to deal with the hardcoded strings.
If you use neither of these methods, unfortunately the best you can really hope for is runtime exceptions (which isn't optimal for obvious reasons).
EDIT:
It seems a SelectQueryBuilder library already exists for the second scenario I suggested.
I found this solution
evaluate an arithmetic expression stored in a string (C#)
SOLUTION:
string conditiontext = "(([age] >= 28) && ([nationality] == \"US\"))";
conditiontext = conditiontext.Replace("[age]", 32)
.Replace("[nationality]","US");
/*VsaEngine*/
var engine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
/** Result will be either true or false based on evaluation string*/
var result = Microsoft.JScript.Eval.JScriptEvaluate(conditiontext, engine);
[Note: This interface is deprecated. But it evaluates any arithmetic expressions and c# expressions]
You could use System.Data and its DataTable.Compute() method.
Here is the code:
public bool CheckCondition()
{
// parameters
(string name, object value)[] variables =new (string name, object value)[1];
variables[0].name = "age";
variables[0].value = 28;
variables[1].name = "nationality";
variables[1].value = "US";
string conditions = "(([age] >= 28) && ([nationality] == 'US'))";
conditions.Replace("[", "").Replace("]", "").Replace("&&", "AND").Replace("||", "OR");
using DataTable table = new DataTable();
foreach (var (name, value) in variables)
table.Columns.Add(name, value is null ? typeof(object) : value.GetType());
table.Rows.Add();
foreach (var (name, value) in variables)
table.Rows[0][name] = value;
table.Columns.Add("_Result", typeof(double)).Expression = conditions
?? throw new ArgumentNullException(nameof(conditions));
return (bool)(Convert.ChangeType(table.Compute($"Min(_Result)", null), typeof(bool)));
}
Take a look at this code:
System.Web.SessionState.HttpSessionState ss = HttpContext.Current.Session["pdfDocument"] ?? false;
if ((Boolean)ss)
{
Label1.Text = (String)Session["docName"];
}
Basically I want to check if HttpContext.Current.Session["pdfDocument"] is not null, and if it isn't to cast to Boolean, then check if its true or false.
I'm trying to avoid nested if statements and figured there would be a more elegant way to do it. I'm therefore only interested in answers that contain the conditional ? operator.
Any tips?
Why do you use ss variable?
What about this:
if (HttpContext.Current.Session["pdfDocument"] != null)
{
Label1.Text = (String)Session["docName"];
}
object ss = HttpContext.Current.Session["pdfDocument"] ?? false;
if ((Boolean)ss)
{
Label1.Text = (String)Session["docName"];
}
Not sure exactly what you're asking for, how about:
System.Web.SessionState.HttpSessionState ss;
Label1.Text = (Boolean)((ss = HttpContext.Current.Session["pdfDocument"]) ?? false) ? (String)Session["docName"] : Label1.Text;
Should leave ss with either a valid session or null, avoids the problem of trying to store false to ss and completely skips the subsequent 'if'. Though there's a repetition of Label1.Text.
Note: this has been edited to take account of the comment by Dave below.
The problem is that you can't do this:
SessionState.HttpSessionState ss = false;
Try putting your nested ifs into an extension method then call that instead.
HttpContext.Current.Session is an System.Web.SessionState.HttpSessionState object, which is a hash or dictionary, as some may call it, of different objects, so unless you're storing an HttpSessionState object as the "pdfDocument" location the first line is incorrect.
If you're actually storing a bool in the "pdfDocument" location which may or may not already be in this slot, you could cast that directly to a bool and null coalesce it: var ss = (bool)(HttpContext.Current.Session["pdfDocument"] ?? false);.
If you're possibly storing some other kind of object in the "pdfDocument" location you could just see if it's currently at that location by checking for null: var ss = HttpContext.Current.Session["pdfDocument"] != null;.
You can try this, though I don't know if it fits your aesthetics:
bool isPdfDocumentSet =
bool.TryParse((HttpContext.Current.Session["pdfDocument"] as string,
out isPdfDocumentSet)
? isPdfDocumentSet
: false;
EDIT: There is actually an even more concise way of doing it:
bool isPdfDocumentSet =
bool.TryParse(HttpContext.Current.Session["pdfDocument"] as string,
out isPdfDocumentSet) && isPdfDocumentSet;
I think the closest you will get to the solution taking that path is following:
System.Web.SessionState.HttpSessionState ss = HttpContext.Current.Session["pdfDocument"];
if (ss != null)
{
Label1.Text = (String)Session["docName"];
}