This question already has answers here:
Why does is operator behave like == operator?
(3 answers)
Using "is" keyword with "null" keyword c# 7.0
(2 answers)
Closed 2 years ago.
I was teaching my students how to write a function. I used a simple algorithm to determine if a char value is an actual letter (and not a digit or something else).
So I actually typed what my student said (playing dumb on purpose): "if (letter is 'A') {...}"
To my surprise this didn't cause a compiler error. I added the same check for 'B' and 'C' and my program can now determine that A, B and C are indeed letters.
Why does that work? And WHAT exactly am I comparing here?
I'm not actively using type comparisons, which is what the internet keeps turning up.
I did an additional experiment with other values:
char l = 'A';
if (l is 'A')
{
Console.WriteLine("l 'A'...");
}
if (l is "A")
{
// Doesn't compile.
}
int x = 15;
if (x is 15)
{
Console.WriteLine("X is 15.");
}
if (x is 5.6)
{
// Also doesn't compile.
}
As far as I can tell "is" functions as an extended version of the equality (==) operator that also enforces the same type. But I can't find any documentation on it.
is might have two meanings, depending on which version of C# you have.
In older C# versions, is was short for "is assignable to" or "is assignable from", depending on how you read the code in your head. It wouldn't work for the code in your class because it expects a type on the right-hand side, but I include it here for completeness. It's also useful as an efficient and portable null check, ie variable is object is a better way to write variable != null1.
In newer C# versions, is can also be used for pattern matching. This was introduced in C# 72 and extended in C# 8, with more coming in 9. Specifically, the code in the question creates a Constant Pattern expression.
Here's another fun way to see this work. Coming in C# 9, instead of writing a check like this:
if (!string.IsNullOrEmpty(mystring))
You could instead write3
if (mystring is {Length:>0})
Which is nice because it's shorter and you could make an argument removing the negation makes it easier to understand.4
At least, according to one of the developers on the C# team at Microsoft. But what would he know? He only built the thing.
Really, C# 6 if you count exception filters.
Jared Parsons again.
I'd reject that argument on the grounds any gains in removing the negation are less than the subtlety introduced in how we validate for null. But you could try the argument ;) And before anyone asks, I have no idea at this time how the two options perform.
Related
I recall an assigment in one of my computer science classes that involved symbolic differentiation with Common Lisp. The properties of common lisp allows you to take an equation and apply symbolic manipulation.
My question is, are there any libraries and programming languages within the .Net framework that allows symbolic manipulation? I'd prefer using C# to solve this. I've already looked at this link but it doesn't give concrete answers.
Let me explain my situation in more detail.
Suppose I have conditional formula, the entirety as a String.
Each name 1DPZ_XY represents an integer variable.
Each of these variables have already been assigned a value.
"
{
1DPZ_a2 = (2 OR 3)
AND
(
1DPZ_a6 = 9
OR
1DPZ_b3 = (3 OR 7)
AND
(
1DPZ_b4 = 8
OR
1DPZ_b5 = 2
OR
1DPZ_b6 = (4 OR 2)
)
)
}
"
Obviously this formula will return either true or false.
How can I convert this String logic into a if-statement I can interact with?
You can parse your string and build a .NET Expression Tree from it. You can then manipulate that expression tree to evaluate it, print it, or transform it (typically using an ExpressionVisitor).
This is just a wondering question for the c# language. I have checked in the MSDN operators and can't see anything close.
When I use LINQ to XML to retrieve some elements, I am passing some lambda expressions in WHERE methods to select specific elements.
But I can see that I am using the following statement which annoys me a bit.
bool myCondition;
// some codes
var elements = xDocument.Descendants("items").
Where(x=>x.Attribute("id")!=null&&
(myCondition)x.Element("blah").Value=="blah":
x.Element("blah").Value!="blah").ToList();
But somehow I keep writing to code as below(no idea why :)):
// some codes
var elements = xDocument.Descendants("items").
Where(x=>x.Attribute("id")!=null&&
x.Element("blah").Value?myCondition="blah").ToList();
I kind of see the boolean myCondition as !(exclamation mark) or =(equal sign).
if true then = if false then !.
I just wonder would that be any possibility in the future to add these types of operators? or there are some better operators that would shorten my condition?
Would this work with any other programming language out there? maybe javascript?
and if you are downgrading then please tell why.
You can already express that condition in C# without conditional operator:
myCondition?
xDocument.Element("item").Value=="blah":
xDocument.Element("item").Value!="blah"
is the same as:
myCondition == (xDocument.Element("item").Value == "blah")
Whether it is more readable is open question. You may consider having helper method with good name instead.
I'm trying to add a basic constraint to my solver foundation by doing the following:
model.AddConstraint("c1", x % y == 0);
I get a compile error saying "Operator '%' cannot be applied to operands of type 'Microsoft.SolverFoundation.Services.Decision' and 'Microsoft.SolverFoundation.Services.Decision'".
This makes sense since a lot of operators aren't supported. However, a lot of the operators that aren't supported (sin, cos, tan, etc.) are available as specific methods on the Model class such as below:
model.AddConstraint("c1", Model.Sum(x,y) == 0);
If I replace "Sum" with "Mod", there is no method available.
Any ideas on how to perform a modulo operation in Solver Foundation? According to the documentation here, it is supported.
I am going to start using reflector to dig through the code, but I figured I would post it on here also. If I find a solution, I will update my question to include the answer.
Really interesting, I wanted to write the exact same question at SO :-)
I found out that a Mod operator is defined for the OML language at http://msdn.microsoft.com/en-us/library/ff818505(v=vs.93).aspx.
There is an overload of the AddConstraint method, that accepts an expression string(I guess an OML expression?) instead of the Term. Unfortunately, I don't know the right formatting, but once we get the knack out of it, we would be able to use all of the other operators as well.
EDIT
It looks like not every OML expression described in API is working. For example,
SolverContext sc = SolverContext.GetContext();
Model m = sc.CreateModel();
m.AddDecision(new Decision(Domain.IntegerRange(0,10), "a"));
m.AddDecision(new Decision(Domain.IntegerRange(0, 10), "b"));
m.AddConstraint(null, "a > 0");
m.AddConstraint(null, "b == Plus[a,2]");
The Plus[x,y] in this case is working and the solver computes the following decision
a: 1,
b: 3
But if I replace the last constraint with this one
m.AddConstraint(null, "b == Mod[a,2]");
I get an OmlParseException ("Failed to parse OML model. Expression: Mod[a,2]."). I guess we are on our own here and purhaps the best thing we can do is sticking with the answer of user141603.
I don't see Mod at http://msdn.microsoft.com/en-us/library/ff525341(v=vs.93).aspx, but here's a workaround:
Model.Floor(Model.Quotient(x,y))==Model.Ceiling(Model.Quotient(x,y))
This is only true if x/y is an integer, and so x%y==0.
There are also other ways of combining the allowed operators to check if it is divisible. My favorite (though I wouldn't recommend it because of floating point precision) is
Model.Sin(Math.PI*Model.Quotient(x,y))==0
What I want to do is be told the type, value (if there is one at compile-time) and other information (I do not know what I need now) of a selection of an expression.
For example, if I have an expression like
int i = unchecked((short)0xFF);
selecting 0xFF will give me (Int32, 255), while selecting ((short)0xFF) will give me (Int16, 255), and selecting i will give me (Int32, 255).
Reason why I want such a feature is to be able to verify my assumptions. It's pretty easy to assume that 0xFF is a byte but it is actually an int. I could of course refer to the C# Language Specifications all the time, but I think it's inefficient to have to refer to it everytime I want to check something out. I could also use something like ANTLR but the learning curve is high.
I do intend to read the entire specs and learn ANTLR and about compilers, but that's for later. Right now I wish to have tools to help me get the job done quickly and accurately.
Another case in point:
int? i = 0x10;
int? j = null;
int x;
x = (i >> 4) ?? -1;//x=1
x = (j >> 4) ?? -1;//x=-1
It may seem easy to you or even natural for the bottom two lines in the code above. (Maybe one should avoid code like these, but that's another story) However, what msdn says about the null-coalescing operator is lacking information to tell me that the above code ((i>>4)??) is legal (yet it is, and it is). I had to dig into grammar in the specs to know what's happening:
null-coalescing-expression
conditional-or-expression
conditional-and-expression
exclusive-or-expression
and-expression
equality-expression
relational-expression
shift-expression
shift-expression right-shift additive-expression
... (and more)
Only after reading so much can I get a satisfactory confirmation that it is valid code and does what I think it does. There should be a much simpler way for the average programmer to verify (not about validity, but whether it behaves as thought or not, and also to satisfy my curiosity) such code without having to dive into that canonical manual. It doesn't necessary have to be a VS plugin. Any alternative that is intuitive to use will do just as well.
Well, I'm not aware of any add-ins that do what you describe - however, there is a trick you can use figure out the type of an expression (but not the compile-time value):
Assign the expression to a var variable, and hover your mouse over the keyword var.
So for example, when you write:
var i = unchecked((short)0xFF);
and then hover your mouse over the keyword var, you get a tooltip that says something like:
Struct System.Int16
Represents a 16-bit signed integer.
This is definitely a bit awkward - since you have to potentially change code to make it work. But in a pinch, it let's you get the compiler to figure out the type of an expression for you.
Keep in mind, this approach doesn't really help you once you start throwing casts into the picture. For instance:
object a = 0xFF;
var z = (string)a; // compiles but fails at runtime!
In the example above, the IDE will dutifully report that the type of var z is System.String - but this is, of course, entirely wrong.
Your question is a little vague on what you are looking for, so I don't know if "improved" intellisense solves it, but I would try the Productivity Power Tools.
This question already has answers here:
Closed 13 years ago.
Most of us write conditionals like:
if (resultIndex == 0)
...but occaisionally I come across someone writing them like:
if (0 == resultIndex)
...and interestingly those people have been authors and seemingly pretty hot coders.
So why do some people choose the 'backwards' style? Is there some history behind it? Readabililty?
Duplicate: Why does one often see “null != variable” instead of “variable != null” in C#?.
It is a legacy from C, where a common bug would be to write
if (x = 0) {...}
If you taught yourself to write these tests the other way around, then the compiler would complain when you made the == typo, instead of silently adding a bug.
This has been asked numerous times before though I can't seem to find the Dup.
Essentially, this style is a hangover from C where a common mistake for
if (c == 5) //Comparison
was
if (c = 5) //Assignment
In the latter case, the compile rwould not complain so people wrote it like so to reduce the likelyhood of this happening
if (5 == c)
Because (in C, where most of those programmers probably learned; I can't remember if this holds in C#) if you leave off a = character in the 'regular' style, you'll overwrite the value you are trying to compare (and you'll be checking the boolean value of the assignment). If you do it in the 'backwards' style, you'll get a compiler error.
In C#, integer values are not implicitly casted to boolean, so if (a = 0) yields a compiler error and does not compile. Hence, this practice is outdated and totally unnecesary in C#.
The main reason behind this I believe is to prevent mistakes such as:
if (variable = 0)
Where you assign in the condition instead of comparing.
The reason this would fail the other way around is because you have a constant on your left side of the expression.
So if you were to mistakenly write:
if (0 = variable)
You would get a compilation error from trying to assign something to a constant.
In my opinion this has more in regard to programming style, but still might be a good tip for new programmers. But once you're a little more experienced, errors such as this don't happen and if they do you should be able to track them down pretty easily.