Question on how these 2 lines of code work - c#

I am reading this article on how to work with AD via C#. Half way through the article, the below code is presented.
The user account properties are checkboxes. Does anyone have any idea what the below line of code will return for a checked checkbox? What if more than 1 checkbox is checked? I'd have thought a bool being returned would be more intuitive?
//Add this to the create account method
int val = (int)newUser.Properties["userAccountControl"].Value;
//newUser is DirectoryEntry object
Why do we do the logical or below? How does it work between an int and the second value (is that a byte?)
newUser.Properties["userAccountControl"].Value = val | 0x80000;
//ADS_UF_TRUSTED_FOR_DELEGATION
I know that sounds very naive...
Thanks

The userAccountControl property contains a two byte value in which each single bit has a significant meaning. If the bit is on, then some option is used - if it's not on, then the option is not present.
This is more compact and more space optimized than having a gazillion of booleans. Also, many "older" Win16 and Win32 API just simply work this way.
The bitwise "AND" operator is used to check for the presence of such a single bit:
if (newUser.Properties["userAccountControl"].Value & 0x400 == 0x400)
in this case, the 0x400 bit is set.
In order to actually set a bit, you use the bitwise "OR" operator:
newUser.Properties["userAccountControl"].Value = val | 0x800
This sets the "0x800" bit.
It's basic bit-wise boolean logic, really. A bit messy, indeed - but .NET has some help to make things a bit easier (check out the BitArray data type, for instance)

userAccountControl is a flag field, that's why they put it into an int.
See http://support.microsoft.com/kb/305144 for more information.

Based on the information that you are giving, I would guess that they are using a flags type system to indicate selected items. Each option has a specific value, and they are added up so you can get back which are selected.
This would be proved by the logical or that is used to see if a specific value is included.

Related

C# literal int comparison versus creating a const for comparison

I'm reviewing code review suggestions written from/to various developers and came across an interesting one.
Someone originally wrote a basic comparison in LINQ (EF to be specific):
myTable.Where(i => i.MyValue == 1);
Where 1 is an unchanging TypeId stored in the database.
The suggestion was to remove the hard coded value of 1 in favor of a const. So for example it would be rewritten as:
const int valueId = 1;
myTable.Where(i => i.MyValue == valueId);
From the suggestion point of view I get where they were coming from with the const since the code only ever needs a single copy of this value. But perhaps the compiler is smart enough to recognize that this is an unchanging value and treats it similarly.
So the question remains, does this kind of code refactor actually hold any weight other than eliminating "magic numbers"?
At this level, it is highly unlikely it matters what is produced at the compiler. It is likely the same anyway. The point is, what is safer for usage and easier to understand? Does '1' represent anything in particular except the literal value '1'? Based on the code snippet, I would guess that it does, and that is very good grounds for introducing a constant field because you now know exactly what is being checked against here.
Is this literal value '1' used in any other places that would need to be changed if the value change, for example, to '2'? If so, that also is very good grounds for introducing a constant field because now you only have to change the value in a single place, rather than search your entire code base, and most likely missing at least one instance.
Also, credit to Ixrec from Programmers, valueId is a terrible name for a constant as it does not say what the value is. A better name would be answersId, if, for example, the '1' represented answers while '0' represented questions and '2' represented comments.
First of all, both versions of the code will compile to exactly the same IL.
A constant is not a variable. Any usage of a constant is replaced at compile-time by it's value.
There are 2 advantages of using a const instead of a literal
The constant can be defined once and used in many places. So if you ever need to change the value of the constant, you only need to change it in one place*
You can give a meaningful name to the constant.
(*) Never change value of a public const field - all other assemblies using this constant will have to be recompiled to use the updated value.

If statement not working as expected on combined enum value

This is a quirky one.
I have the following code...
foreach (IScanTicket ticket in this) {
if (ticket.Status == TicketStatus.Created || ticket.Status == (TicketStatus.Transfered | TicketStatus.Created))
return ticket;
}
}
When I run this, where the status is Created|Transferred, the if statement seems to fail (not do what it's suppose to).
The interesting thing is that if I debug and step through the code and watch the statement, it always returns TRUE in my debugger, yet it fails to enter the block when I step through the code.
Why would the debugger show that the statement is true, yet continue like it's not? It's like what the debugger is telling me fibs.
Has anyone ever experienced this?
P.S. I'm using Xamarin studio 5.9.7
Too long for a comment:
Actually, the [Flags] attribute does not change an enum's semantics at all, it's most popularly used by the ToString method to emit a series of names rather than a number for a combined value.
Let's say your enum was declared like this (without the Flags attribute):
enum TicketStatus
{
Created = 1,
Transferred = 2,
Sold = 4
}
You could still combine different members and do any arithmetic that applies to a Flags enum:
TicketStatus status = TicketStatus.Created | TicketStatus.Transferred;
However, the following will print 3:
Console.WriteLine(status);
But if you add the [Flags] attribute, it will print Created, Transferred.
Also, it's important to note that by TicketStatus.Created | TicketStatus.Transferred you're really doing a bitwise OR on the underlying integer value, notice how in our example that the assigned values are unambiguously combinable:
Created : 0001
Transferred: 0010
Sold: 0100
Therefore a value of 3 can be unambiguously determined as a combination of Created and Transferred. However if we had this:
enum TicketStatus
{
Created = 1, // 0001
Transferred = 2, // 0010
Sold = 3, // 0011
}
As it is obvious by the binary representations, combining values and checking against members is problematic as combined members could be ambiguous. e.g. what is status here?
status = TicketStatus.Created | TicketStatus.Transferred;
Is it Created, Transferred or is it really Sold? However, the compiler won't complain if you try to do it, which could lead to hard to track down bugs like yours, where some check is not working as you expect it to, so it's on you to ensure the definition is sane for bitwise mixing and comparing.
On a related note, since your if statement is really only checking if the ticket has a Created status, regardless of being combined with other members, here's a better way to check for that (.NET >= 4):
status.HasFlag(TicketStatus.Created)
or (.NET <4):
(status & TicketStatus.Created) != 0
As to why your enum did not work as expected, it is almost certainly because you did not explicitly specify unambigously bitwise combinable values to its members (typically powers of two).
Thanks to #MarcinJuraszek and #YeldarKurmangaliyev.
Seems the [Flags] attribute wasn't set on the enum as I originally thought. Adding this attribute now makes the enum work in either combination.
So it seems that not having this attribute effects the order of joined enum values.

is Convert.toInt32(boolean) the only way in c# to do this?

I have some code in c# which needs to increment a number by 1 if a certain boolean value is true, but else it needs to say the same. The only method i've found using the Immediate window in VS 2012 is by + Convert.ToInt32(boolean).
Am I missing something obvious in here somewhere? I thought since a boolean is basically true (1) or false(0) (let's forget about FileNotFound), it would be easier to coerce a boolean to an Int value.
edit:
false is 0, not 1
edit2: my original edit got swallowed up. I'm currently doing a nullcheck on the number (the number is a nullable int field from a Dynamics CRM 2011 entity). Is it possible to keep that nullcheck?
I don't think that adding boolean flag to some value is very readable solution. Basically you want to increment (i.e. add 1) value if flag is true. So, simple if check will clearly describe your intent add do the job:
if (flag) value++;
UPDATE: According to your edit, you want to do two things:
Set default value to your nullable value
Increment value if some condition is true.
To make your code clear, I would not try to put both things in one line. Make your intent explicit:
value = value ?? 0; // 1
if (flag) // 2
value++;
The simple solution would be like so:
val += flag ? 1 : 0;
The fact is that a .NET boolean is simply a completely different type from integer (unlike in, say, C++, where it's a "renamed" integer). The fact, that it is actually implemented using an integer value, is implementation detail and not to be relied upon. In fact, you can do a lot of strange things when you mess with the actual value of the boolean (for example, using direct memory manipulation or overlapping structure fields) - the consistency goes away.
So, don't work with the "actual value of boolean". Simply expect the two possible values, true and false, and work with those.
You can still use the null-check and add the value according to the boolean, like this:
obj.Variable = (obj.Variable ?? 0) + (yourBoolean ? 1 : 0);
//obj is the instance of your object
//Variable is the nullable integer
//yourBoolean is the bool to check against
Object.variable is int variable OR Nullable? If Int varable it's default value is 0, and you can just write like this: Object.variable+=bool?1:0, else can use it: Object.variable=Object.variable??0+bool?1:0

Fast way to check for existence and then insert into a SortedList

Whenever I want to insert into a SortedList, I check to see if the item exists, then I insert. Is this performing the same search twice? Once to see if the item is there and again to find where to insert the item? Is there a way to optimize this to speed it up or is this just the way to do it, no changes necessary?
if( sortedList.ContainsKey( foo ) == false ){
sortedList.Add( foo, 0 );
}
You can add the items to a HashSet and the List, searching in the hash set is the fastest way to see if you have to add the value to the list.
if( hashSet.Contains( foo ) == false ){
sortedList.Add( foo, 0 );
hashSet.Add(foo);
}
You can use the indexer. The indexer does this in an optimal way internally by first looking for the index corresponding to the key using a binary search and then using this index to replace an existing item. Otherwise a new item is added by taking in account the index already calculated.
list["foo"] = value;
No exception is thrown whether the key already exists or not.
UPDATE:
If the new value is the same as the old value, replacing the old value will have the same effect than doing nothing.
Keep in mind that a binary search is done. This means that it takes about 10 steps to find an item among 1000 items! log2(1000) ~= 10. Therefore doing an extra search will not have a significant impact on speed. Searching among 1,000,000 items will only double this value (~ 20 steps).
But setting the value through the indexer will do only one search in any case. I looked at the code using Reflector and can confirm this.
I'm sorry if this doesn't answer your question, but I have to say sometimes the default collection structures in .NET are unjustifiably limited in features. This could have been handled if Add method returned a boolean indicating success/failure very much like HashSet<T>.Add does. So everything goes in one step. In fact the whole of ICollection<T>.Add should have been a boolean so that implementation-wise it's forced, very much like Collection<T> in Java does.
You could either use a SortedDictionary<K, V> structure as pointed out by Servy or a combination of HashSet<K> and SortedList<K, V> as in peer's answer for better performance, but neither of them are really sticking to do it only once philosophy. I tried a couple of open source projects to see if there is a better implementation in this respect, but couldn't find.
Your options:
In vast majority of the cases it's ok to do two lookups, doesn't hurt much. Stick to one. There is no solution built in.
Write your own SortedList<K, V> class. It's not difficult at all.
If you'r desperate, you can use reflection. The Insert method is a private member in SortedList class. An example that does.. Kindly dont do it. It's a very very poor choice. Mentioned here for completeness.
ContainsKey does a binary search, which is O(log n), so unless you list is massive, I wouldn't worry about it too much. And, presumably, on insertion it does another binary search to find the location to insert at.
One option to avoid this (doing the search twice) is to use a the BinarySearch method of List. This will return a negative value if the item isn't found and that negative value is the bitwise compliment of the place where the item should be inserted. So you can look for an item, and if it's not already in the list, you know exactly where it should be inserted to keep the list sorted.
SortedList<Key,Value> is a slow data structure that you probably shouldn't use at all. You may have already considered using SortedDictionary<Key,Value> but found it inconvenient because the items don't have indexes (you can't write sortedDictionary[0]) and because you can write a find nearest key operation for SortedList but not SortedDictionary.
But if you're willing to switch to a third-party library, you can get better performance by changing to a different data structure.
The Loyc Core libraries include a data type that works the same way as SortedList<Key,Value> but is dramatically faster when the list is large. It's called BDictionary<Key,Value>.
Now, answering your original question: yes, the way you wrote the code, it performs two searches and one insert (the insert is the slowest part). If you switch to BDictionary, there is a method bdictionary.AddIfNotPresent(key, value) which combines those two operations into a single operation. It returns true if the specified item was added, or false if it was already present.

Is there any plugin for VS or program to show type and value etc... of a C# code selection?

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.

Categories

Resources