I have this sample code:
DirectoryEntry _entry = new DirectoryEntry(
connectionString,
this.userPrinicipalName,
this.password,
AuthenticationTypes.SecureSocketsLayer & AuthenticationTypes.Encryption);
How come I am allowed to make the amp in the last parameter? I am use to java where I have never seen this kind of witchcraft before AND I am new to C# - So can anyone tell me what it is and how I am allowed to do it?
Thanks in advance
Those are probably integers, so you are just doing an binary and (&) of their values.
If you have 1 and 2 the result would be 0 01 & 10 = 00.
Nobody else has pointed this out, but
AuthenticationTypes.SecureSocketsLayer & AuthenticationTypes.Encryption
is a bit weird because SecureSocketsLayer and Encryption are both 2.
So you might as well just put one or the other, not both...
If they were different and you did want to combine them, you should use the OR operator, |, not the AND operator, &.
In this page Authentication Types. It says "This enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values." Meaning that each attribute has its own bit, so the bits can be combined to have multiple attributes.
This is most likely an enum that has the [Flags] attribute on it. This attribute allows bitwise operators to be used on the enum.
AuthenticationTypes has a FlagsAttribute. Therefore you are able to combine different enumerated values into a composite enum value through for example bitwise OR operations.
Related
I would like to pass some operators through as querystring parameters so that I can convert them, along with a value into an SQL query. The idea would be to let the querystring parameters dictate wether the page returns search results where prices are equal to, greater than or equal to, greater than, less than or less than or equal to as follows:
=, >=, >, < and <=
I'm not sure what the best practise is for passing these operators through is, could anybody help me out? Would you pass through ascii codes or simply text like e, gte, gt, lt, lte and then convert them on results page that builds the query?
Thanks guys!
As user Kon said, use HttpServerUtility.UrlEncode. I've once written a tiny little class to simplify working with query strings so that I do not have to call Server.UrlEncode.
As a side note, keep an eye on SQL injection aka Little Bobby Tables:
(Source)
Server.UrlEncode
You can use eq, ne, gt, lt, ge, le, sa, eb, ap like in the examples below
ge means >=
GET [base]/subjects?grade=ge90
le means <=
GET [base]/encounter?length=le20
More information you can find on those websites:
https://www.hl7.org/fhir/stu3/search.html#number
https://www.hl7.org/fhir/stu3/search.html#prefix
URL encoding is definitely what you're looking for. Take a look at the Web.Utils namespace. http://msdn.microsoft.com/en-us/library/system.web.util.httpencoder.aspx
I haven't really used bitwise enums before, and I just want to make sure my testing is correct. I am most interested in testing for the values None and All. We receive data from a webservice that utilises this enum to categorise certain pieces of the data. Given that, I am assuming that nether None nor All would ever be combined with any other value.
Given the following bitwise enum definition;
[System.FlagsAttribute()]
public enum TrainingComponentTypes : int
{
None = 0,
AccreditedCourse = 1,
Qualification = 2,
Unit = 4,
SkillSet = 8,
UnitContextualisation = 16,
TrainingPackage = 32,
AccreditedCourseModule = 64,
All = 127,
}
I read the following quote on this MSDN site about FlagAttributes;
Use None as the name of the flag
enumerated constant whose value is
zero. You cannot use the None
enumerated constant in a bitwise AND
operation to test for a flag because
the result is always zero. However,
you can perform a logical, not a
bitwise, comparison between the
numeric value and the None enumerated
constant to determine whether any bits
in the numeric value are set.
Does a logical comparison in this instance refer to a normal equality test for enums?
For example;
TrainingComponentTypes tct = TrainingComponentTypes.None;
if (tct == TrainingComponentTypes.None)
{ ... }
For a bitwise comparison, I am performing the following;
TrainingComponentTypes tct = TrainingComponentTypes.AccreditedCourse | TrainingComponentTypes.Qualification | TrainingComponentTypes.TrainingPackage;
Assert.IsTrue((tct & TrainingComponentTypes.AccreditedCourse) == TrainingComponentTypes.AccreditedCourse, "Expected AccreditedCourse as part the enum");
Assert.IsFalse((tct & TrainingComponentTypes.SkillSet) == TrainingComponentTypes.SkillSet, "Found unexpected SkillSet as part the enum");
Lastly, when testing for all, I have tried both a logical, and bitwise comparison, and they both return the same. Should I be using one over the other here? For example;
TrainingComponentTypes tct = TrainingComponentTypes.All;
Assert.IsTrue((tct & TrainingComponentTypes.All) == TrainingComponentTypes.All, "Expected All as part the enum");
Assert.IsTrue((tct) == TrainingComponentTypes.All, "Expected All as part the enum");
// The follow also pass the assertion for a value of All
Assert.IsTrue((tct & TrainingComponentTypes.Qualification) == TrainingComponentTypes.Qualification, "Expected Qualification as part the enum");
Assert.IsTrue((tct & TrainingComponentTypes.TrainingPackage) == TrainingComponentTypes.TrainingPackage, "Expected TrainingPackage as part the enum");
So in summary, I'd like to know the following about Bitwise enums;
Is my understanding of a logical
comparison correct given my example
above?
Is the way I am performing
a bitwise comparison correct?
What is the right way to handle the "All"
value (bitwise or logical). I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes. I can't see why we would, but then, you never know?
Am I right in assuming that switch
statements basically shouldn't be
used for bitwise enums (given none
is appears to be a special case and
requires a logical comparison)?
Thanks,
Chris
Short answer: Yes :)
Longer:
1) All operations are performed on the integer value of the flags variable, so you can think about them in terms of this.
2) Yes.
3) Either works. However, it's worth noting that if someone shoves an invalid value into a variable then the == TrainingComponentTypes.All version will fail. For example:
var badValue = (TrainingComponentTypes)128 | TrainingComponentTypes.All;
// now badValue != TrainingComponentTypes.All
// but (badValue & TrainingComponentTypes.All) == TrainingComponentTypes.All
For this part:
I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes.
I'm not sure you fully understand how the enum works under the covers.
The value of All is:
127 = 1111111 (binary)
The other values are:
AccreditedCourse = 0000001
Qualification = 0000010
Unit = 0000100
SkillSet = 0001000
UnitContextualisation = 0010000
TrainingPackage = 0100000
AccreditedCourseModule = 1000000
As you can see, All is simply the bitwise | of all these values together. You can't combine any other TraningComponentTypes with All, because All already includes them! Also, if you combine them all together with | yourself it's exactly the same as using All directly (so, All is simply a convenience when you define it inside an enum).
4) You could use it to check for None or All but not for other values.
It's worth noting that there is a convenience method on Enum that will do these checks for you: Enum.HasFlag.
Is my understanding of a logical comparison correct given my example above?
Yes, logical in this context means the equality and inequality operators.
Is the way I am performing a bitwise comparison correct?
Yes, but there is an easier way: Enum.HasFlag. For example:
tct.HasFlag(TrainingComponentTypes.Qualification)
instead of:
(tct & TrainingComponentTypes.Qualification) == TrainingComponentTypes.Qualification
What is the right way to handle the "All" value (bitwise or logical). I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes. I can't see why we would, but then, you never know?
I think it is better to define All in the enum itself as the bitwise OR of all its parts. But you'll see people do it both ways.
Am I right in assuming that switch statements basically shouldn't be used for bitwise enums (given none is appears to be a special case and requires a logical comparison)?
No, not at all. Feel free to use them is switch statements. The case values must be constants but they can be expressions and are tested for equality. The compiler will tell you if you do something silly like try to use the same case value twice.
Yes.
Yes
Both logical and bitwise could be used. Usage depends on whether all is all bits set or just the bitwise OR of all the values you've defined.
Yes, but not because of None. A switch compares a single value, whereas a bit field can obviously have multiple values.
As others have noted Enum contains HasFlag().
1 and 2 - yes, however there is a way to make it a little easier to read:
TrainingComponentTypes tct = TrainingComponentTypes.AccreditedCourse | TrainingComponentTypes.Qualification;
Assert.IsTrue(tct.HasFlag(TrainingComponentTypes.AccreditedCourse), "Expected AccreditedCourse as part the enum");
3 - I am not sure if you need All value at all. I would remove it.
4 - Yes, switch statement usually doesn't make sense for Flags enumerations.
"3.What is the right way to handle the "All" value (bitwise or logical). I am not sure if we'd ever receive a value where All was combined with other TrainingComponentTypes. I can't see why we would, but "
It seems you misunderstand how the bitwise enum values work. 'All' is always combined with other values, in fact it is the combination of all the values. Looking at the binary values for your enum:
None = 0,
AccreditedCourse = 1,
Qualification = 10,
Unit = 100,
SkillSet = 1000,
UnitContextualisation = 10000,
TrainingPackage = 100000,
AccreditedCourseModule = 1000000,
All = 1111111
does that help your understanding?
1&2 look fine
3.
All as you have it defined can't be combined with anything without losing data. If "all" is a real value that you expect to receive from the server you should probably change it to 128.
otherwise it is a convenience value that you can use to test if any value is set... you shouldn't need this unless your flag values are sent as binary data and packed in a byte that may contain other data.
4.
Switch statements could be used but will not work well if/when you have values that have more than one flag, if there are small subsets of valid flag combinations they can still be useful.
In model
as_enum :shifts, { day_shift: 0,
evening_shift: 1,
night_shift: 2,
}, accessor: :bitwise
And in Views
Model.enum_collection(:shifts)
Using a string.CompareTo(string) i can get around this slightly but is not easy to read and i have read on that locallity settings might influence the result.
Is there a way to just simply use < or > on 2 Strings in a more straightforward way?
You can overload operators but you seldom should. To me "stringA" > "stringB" wouldn't mean a damn thing, it's not helping readability IMO. That's why operator overloading guidelines advise not to overload operators if the meaning is not obvious.
EDIT: Operator Overloading Usage Guidelines
Also, in case of String I'm afraid you can't do it seeing as you can put operator-overloading methods only in the class in which the methods are defined.
If the syntax of CompareTo bothers you, maybe wrapping it in extension method will solve your problem?
Like that:
public static bool IsLessThan(this string str, string str2) {
return str.Compare(str2) < 0;
}
I still find it confusing for reader though.
The bottom line is, you can't overload operators for String. Usually you can do something like declaring a partial and stuffing your overloads there, but String is a sealed class, so not this time. I think that the extension method with reasonable name is your best bet. You can put CompareTo or some custom logic inside it.
CompareTo is the proper way in my opinion, you can use the overloads to specify culture specific parameters...
You mention in a comment that you're comparing two strings with values of the form "A100" and "B001". This works in your legacy VB 6 code with the < and > operators because of the way that VB 6 implements string comparison.
The algorithm is quite simple. It walks through the string, one character at a time, and compares the ASCII values of each character. As soon as a character from one string is found to have a lower ASCII code than the corresponding character in the other string, the comparison stops and the first string is declared to be "less than" the second. (VB 6 can be forced to perform a case-insensitive comparison based on the system's current locale by placing the Option Compare Text statement at the top of
the relevant code module, but this is not the default setting.)
Simple, of course, but not entirely logical. Comparing ASCII values skips over all sorts of interesting things you might find in strings nowadays; namely non-ASCII characters. Since you appear to be dealing with strings whose contents have pre-defined limits, this may not be a problem in your particular case. But more generally, writing code like strA < strB is going to look like complete nonsense to anyone else who has to maintain your code (it seems like you're already having this experience), and I encourage you to do the "right thing" even when you're dealing with a fixed set of possible inputs.
There is nothing "straightforward" about using < or > on string values. If you need to implement this functionality, you're going to have to do it yourself. Following the algorithm that I described VB 6 as using above, you could write your own comparison function and call that in your code, instead. Walk through each character in the string, determine if it is a character or a number, and convert it to the appropriate data type. From there, you can compare the two parsed values, and either move on to the next index in the string or return an "equality" value.
There is another problem with that, I think:
Assert.IsFalse(10 < 2);
Assert.IsTrue("10" < "2");
(The second Assert assumes you did an overload for the < operator on the string class.)
But the operator suggests otherwise!!
I agree with Dyppl: you shouldn't do it!
I'm browsing an open source .NET twain wrapper and saw this:
[Flags]
internal enum TwDG : short
{ // DG_.....
Control = 0x0001,
Image = 0x0002,
Audio = 0x0004
}
What exactly does that 'Flag' decorator mean? (Is it called a 'decorator'?)
Also, what does the short mean at the end of the enum declaration?
Thanks!
The Flags Attribute is used to allow and decorate the enumeration for bitwise math operations on enum values.
Doing this allows you to add them together, or other operation items.
The Short part defines it as a Short rather than an integer, detail on this is also in the linked URL
It's an attribute. Although others have said that it is necessary so that you can perform bit flipping operations with the enum, this is not true. You can do this with enums without this attribute.
If you have applied the attribute, you get a different ToString() output on the enum which will pretty-print the combined members of a enum value, e.g. "Blue | Red | Orange", instead of "7".
The "short" keyword means that the type for the enum members will be a 16-bit signed integer.
It means that you give a hint, that this enum will be used for "bitwise or" operations
var flags = TwDG.Control | TwDG. Image;
Console.WriteLine(flags.HasFlag(TwDG.Image)); // true
Console.WriteLine(flags.HasFlag(TwDG.Control)); // true
Console.WriteLine(flags.HasFlag(TwDG.Audio)); // false
More info FlagAttribute (Enum.HasFlag was added in Framework 4.0)
Short is saying, that back-type for this enum is not int (which is default option for enums), but short. Also you can specify long, ushort, or any other integer built-in type.
short is another keyword for System.Int16, a two-byte integer ranging from -32,768 to 32,767. By default, an enum's base type is int; in this case, they're attempting to use a smaller data type to store the enumerator values.
Its the flag attribute, you can read up on it here:
http://msdn.microsoft.com/en-us/library/cc138362.aspx
Lets you treat a set of enums a bit flag set.
the short means that the enum is using short instead of an int as its base type.
as for the flags
http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx
This makes an enumeration a bit-flag.
It means you can combine individual values together.
Like:
TwDG value = TwDG.Control | TwDG.Image | TwDG.Audio;
Which would give it a value of 7.
Individual enumeration values usually have a value of 2^n. But can as well be combined like:
[Flags]
public enum Sides
{
Left = 1,
Right = 2,
Up = 4,
Down = 8,
LeftAndRight = 3,
UpAndDown = 12,
AllSides = 15
}
As for [Flag] - you should look here link text
Short - data time, which used to store enum values.
Flags is an attribute; specifically, System.FlagsAttribute.
It means that the compiler lets you use values of type TwDG as a bit-field, i.e., store as many of them as you want in one value like this:
var control = TwDG.Control;
var allTogether = TwDG.Control | TwDG.Image | TwDG.Audio;
Typically, this is done when some code needs to take different (or optional) actions depending on if one of these flags is set. For example, let's say we want to describe the contents of a video file, which might contain audio and picture. You could write:
var imageAndAudio = TwDG.Image | TwDG.Audio;
var muteImage = TwDG.Image;
Then, if you wanted to check if the file contains an audio track, you would "pick out" the Audio flag like this:
var hasAudio = (myValue & TwDG.Audio) != (TwDG) 0;
I've heard them called decorators before (and it is acceptable to label them as such in the community) but for arguments sake and strictly speaking; it is an attribute. It is used to "mark" the enum as a bit flag type.
Here's the MSDN Reference.
I am building a fun little app to determine if I should bike to work.
I would like to test to see if it is either Raining or Thunderstorm(ing).
public enum WeatherType : byte
{ Sunny = 0, Cloudy = 1, Thunderstorm = 2, Raining = 4, Snowing = 8, MostlyCloudy = 16 }
I was thinking I could do something like:
WeatherType _badWeatherTypes = WeatherType.Thunderstorm | WeatherType.Raining;
if(currentWeather.Type == _badWeatherTypes)
{
return false;//don't bike
}
but this doesn't work because _badWeatherTypes is a combination of both types. I would like to keep them separated out because this is supposed to be a learning experience and having it separate may be useful in other situations (IE, Invoice not paid reason's etc...).
I would also rather not do: (this would remove the ability to be configured for multiple people)
if(WeatherType.Thunderstorm)
{
return false; //don't bike
}
etc...
Your current code will say whether it's exactly "raining and thundery". To find out whether it's "raining and thundery and possibly something else" you need:
if ((currentWeather.Type & _badWeatherTypes) == _badWeatherTypes)
To find out whether it's "raining or thundery, and possibly something else" you need:
if ((currentWeather.Type & _badWeatherTypes) != 0)
EDIT (for completeness):
It would be good to use the FlagsAttribute, i.e. decorate the type with [Flags]. This is not necessary for the sake of this bitwise logic, but affects how ToString() behaves. The C# compiler ignores this attribute (at least at the moment; the C# 3.0 spec doesn't mention it) but it's generally a good idea for enums which are effectively flags, and it documents the intended use of the type. At the same time, the convention is that when you use flags, you pluralise the enum name - so you'd change it to WeatherTypes (because any actual value is effectively 0 or more weather types).
It would also be worth thinking about what "Sunny" really means. It's currently got a value of 0, which means it's the absence of everything else; you couldn't have it sunny and raining at the same time (which is physically possible, of course). Please don't write code to prohibit rainbows! ;) On the other hand, if in your real use case you genuinely want a value which means "the absence of all other values" then you're fine.
I'm not sure that it should be a flag - I think that you should have an range input for:
Temperature
How much it's raining
Wind strength
any other input you fancy (e.g. thunderstorm)
you can then use an algorithm to determine if the conditions are sufficiently good.
I think you should also have an input for how likely the weather is to remain the same for cycling home. The criteria may be different - you can shower and change more easliy when you get home.
If you really want to make it interesting, collect the input data from a weather service api, and evaulate the decision each day - Yes, I should have cycled, or no, it was a mistake. Then perhaps you can have the app learn to make better decisions.
Next step is to "socialize" your decision, and see whether other people hear you are making the same decisions.
use the FlagsAttribute. That will allow you to use the enum as a bit mask.
You need to use the [Flags] attribute (check here) on your enum; then you can use bitwise and to check for individual matches.
You should be using the Flags attribute on your enum. Beyond that, you also need to test to see if a particular flag is set by:
(currentWeather.Type & WeatherType.Thunderstorm == WeatherType.Thunderstorm)
This will test if currentWeather.Type has the WeatherType.Thunderstorm flag set.
I wouldn't limit yourself to the bit world. Enums and bitwise operators are, as you found out, not the same thing. If you want to solve this using bitwise operators, I'd stick to just them, i.e. don't bother with enums. However, I'd something like the following:
WeatherType[] badWeatherTypes = new WeatherType[]
{
WeatherType.Thunderstorm,
WeatherType.Raining
};
if (Array.IndexOf(badWeatherTypes, currentWeather.Type) >= 0)
{
return false;
}