|
Today, while reading Francesco Logozzo's blog on "CodeContratcts," [^]:
I came across this interesting use of Enum:
public enum CookPasta { BoilWater, AddPasta, Stir, Strain, Done }
public const CookPasta AddOil = (CookPasta)(-1);
public void Next(CookPasta state)
{
switch (state)
{
case CookPasta.BoilWater:
break;
case AddOil:
break;
}
} And, yes, if you invoke: Next(AddOil), it hits the breakpoint.
So this appears, to me, as kind of a way to "bootleg" extending an Enum which kinds of contradicts my assumptions (as so often happens) about what Enums are and how they are compiled.
I can't imagine a use-case for this, and I suspect using the technique would lead to hard to maintain code (if the use were not documented).
I'm curious if you can see a use-case for this.
thanks, Bill
«OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. » Alan Kay's clarification on what he meant by the term "Object" in "Object-Oriented Programming."
|
|
|
|
|
Well...it works because an enum is a "decorated" integer, and the value of an enum variable doesn't have to be restricted to just the named values:
public enum CookPasta { BoilWater = 1, AddPasta = 2, Stir = 4, Strain = 8, Done = 16}
public const CookPasta AddOil = (CookPasta)(-1);
public void Next(CookPasta state)
{
switch (state)
{
case CookPasta.BoilWater:
break;
case AddOil:
break;
case CookPasta.AddPasta | CookPasta.Strain:
break;
case (CookPasta) 12:
break;
}
} Will compile and work just as well.
As for a use case, yes: Combined bitfields.
public const CookPasta Initialize = (CookPasta) 3;
Though I'd rather see it as
public const CookPasta Initialize = CookPasta.BoilWater | CookPasta.AddPasta;
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Thanks for your response ! I find it interesting that I do get a design-time warning in the VS editor via a pop-up that opens if I mouse-over the "|" character about the fact the [Flags} attribute is not used, but the code certainly works fine.
My "instinctive" negative reaction to taking advantage of these "liberal" syntactic forms with Enum seems to have these components:
1. I can't ... yet ... see a clear example of a real "pay-off" ... a "big win" ... from using these forms.
2. I can imagine looking at code a year later that I wrote, or code someone else wrote, using these forms, and finding it harder to understand, maintain, and debug. imho one "benefit" of using an Enum is that it is self-documenting in a high-level way.
3. While I am just examining, with interest, such tools as Logozzo's CodeContracts, using these forms would break the CodeContracts' 'ccCheck tool (or some other AOP processing ?) which is designed to test for having all case statements that could be evaluated against the values of the Enum present.
But, what is life for but changing instinctive aversions to hypotheses, or conclusions, evaluated by clear reason
«OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. » Alan Kay's clarification on what he meant by the term "Object" in "Object-Oriented Programming."
|
|
|
|
|
I can only agree with your point (2). It's nasty code - with the exception of the "or" form:
public const CookPasta Initialize = CookPasta.BoilWater | CookPasta.AddPasta;
And even then, your compiler is correct that the original enum should have the [Flags] attribute applied. (Mine doesn't, I'm still using VS2010)
And with your point (3) my standard for enum switch statements is:
public void Next(CookPasta state)
{
switch (state)
{
default: throw new ArgumentException("Unrecognised CookPasta state: " + state);
case CookPasta.BoilWater:
DoWaterBoiling();
break;
case CookPasta.AddPasta:
DoAddPasta();
break;
case CookPasta.Stir:
case CookPasta.Strain:
case CookPasta.Done:
break;
}
}
So if I add a state to the enum I will at least get an error if I forget to handle it somewhere.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I like what you just did, and I've learned something new from it, thanks.
Not to beat the dead horse into such smithereens it can't be used by the knackers, but:
When you use this "extend Enum" technique, as in: public const CookPasta AddOil = (CookPasta)(-1);
And, you have not yet written a case statement that handles 'AddOil:
The 'default case of the switch statement will be triggered if the switch statement trigger-parameter is 'AddOil. And, of course, it is unlikely you'll go to the trouble of defining something like 'AddOil unless you are going to handle it in a switch statement (or make use of it in some other way).
But, it kind of "bothers me" that you can have this kind of chimera that's "hanging there" outside the Enum. I may get over that as I digest this further; or, more likely, I'll file it and keep writing Enums the way I do now.
cheers, Bill
«OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. » Alan Kay's clarification on what he meant by the term "Object" in "Object-Oriented Programming."
|
|
|
|
|
How to make a one .net method thread safe. Please explain. class class1(static public method(string,string){})
|
|
|
|
|
|
Hi,
I have a windows form that has one image with a few labels and textboxes. I designed the UI with DPI in the default setting and everything looks exactly the way I want it. When I change the DPI to 125%, the controls start overlapping each other and it looks terrible/unusable. I have tried setting the form's AutoScaleMode from None, Font, DPI, and inherit. It looks like the controls reposition and do not resize. Even though each option is a little different, changing only this one property is definitely not the solution. I checked the other controls and they do not have an AutoScaleMode property. I am using Visual Studio 2012 Pro to develop this app.
I have seen many conversations about this issue but I have yet to find a solid solution. Is there some standard way to handle this anomaly?
Thanks,
Rob
|
|
|
|
|
It is not an anomaly. Look into docking and anchoring, that'll automatically resize them as desired.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I did a quick check and all of my controls are Anchored: Top, Left by default. I noticed that Dock is set to None for the same controls. I'm looking into the Dock property now.
It doesn't look like you can use both at the same time according to MSDN:
"The Anchor and Dock properties are mutually exclusive. Only one can be set at a time, and the last one set takes precedence."
modified 15-Dec-14 14:07pm.
|
|
|
|
|
They're both used to grow/shrink the control, to fill up to empty space as designed. The form might have different dimensions on another PC, due to resolution, size of the screen and the amount of pixels per inch.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
After experimenting with the Anchor property, I have most of the form looking alright after making changes. I don't think the Dock property is going to work for this project. It seems like the labels will need to be manipulated at runtime.
Here is a link to screenshots of the different DPI states:
Screenshots with different DPI settings applied
The top screenshot is how I want it to look across any of the default Windows DPI settings if that is possible.
This is how the Anchor property is configured for each of the controls.
Image upper left - Anchor = Top, Left
Title label upper right - Anchor = Top, Right
Enter Credentials label - Anchor = Top, Left
First Name label - Anchor = Top, Left
First Name textbox - Anchor = Top, Right
Last Name label - Anchor = Top, Left
Last Name textbox - Anchor = Top, Right
Username label - Anchor = Top, Left
Username textbox - Anchor = Top, Right
Abort button - Anchor = Bottom, Right
Backup button - Anchor = Bottom, Right
Any other suggestions as to how to make this work properly?
I'm thinking at this point that I should get the current DPI setting and if it's greater than 96 dpi then move the x-coordinate of the labels.
modified 16-Dec-14 11:59am.
|
|
|
|
|
In WinForms, I'd try and center the title-text on the form; that way it could grow in both directions. I assume you're talking about the title, as the rest looks quite good.
robwm1 wrote: I'm thinking at this point that I should get the current DPI setting and if it's greater than 96 dpi then move the x-coordinate of the labels. If the label is autogrowing, then that "could" be enough. It may overlap other controls though if it grows.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
The title "File Archiver Utility" is in a label. The label itself wraps tightly around the text and the text-align property is set to MiddleCenter and AutoSize is set to True. I might be able to get away with making a banner that includes the logo and title because the image seems to scale or just move the label to the left at launch. I have a couple of other labels that are to the right as well so moving them at launch is probably the best approach.
|
|
|
|
|
robwm1 wrote: The label itself wraps tightly around the text and the text-align property is
set to MiddleCenter and AutoSize is set to True Alignment doesn't help then, as the size of the label is as small as possible. There's no wiggle-room then.
Disable autosizing and make it as wide as the form (the maximum size it should be allowed to be), then anchor it, and then "align middle" will work better.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I made the label the full width from the right edge of the logo graphic to the right edge of the window. Although the text isn't aligned proportionally the same as when DPI is 100%, I would say it falls into the "good enough" category. I'm going to try changing the X location to see how that works.
I could probably put the left edge of the label to where I want the text to be aligned when DPI is 125% and then change the alignment of the box to LeftCenter.
|
|
|
|
|
So getting the DPI setting and changing the control's Location property pretty easily solves this matter. This way I can make the two 'views' look the same without much trouble.
Thanks a lot for your help, Eddy!
|
|
|
|
|
You're welcome
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Suppose I have following code. (not necessarily in one function or even one class.)
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap("[path]");
bmp.Dispose();
How can I detect if bmp was disposed or not? it is not set to null when calling Dispose, but trying to check a property (ef width and height) to see if it is a valid property immediately results in an exception being thrown.
I searched google, but found not real satisfactory option. I try to set bmp = null where I can after dispose, but this is not always and option. (for one thing, this application is a heritage of someone else )
thanks.
|
|
|
|
|
One somewhat horrible way of doing this is:
Bitmap bitmap = new Bitmap(200, 200);
IntPtr hBitmap1 = bitmap.GetHbitmap();
bitmap.Dispose();
try
{
IntPtr hBitmap2 = bitmap.GetHbitmap();
}
catch (ArgumentException ex)
{
Console.WriteLine("Bitmap has been disposed!");
}
Otherwise, you might try figuring out how to test the native handle.
[edit] BTW, I tried reflection to see if Bitmap or Image has a "disposed" field or property. No such luck. [/edit]
Marc
|
|
|
|
|
There is no way to find out if an object is disposed AFAIK, other than to try and use it and catch the ObjectDisposedException exception.
The problem is that Dispose releases all memory for the object, so there is nothing there at the reference instance to hold info for "this is disposed"!
You could add your own bool and check that, but it does seem like a nasty kludge.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
You could derive a class of your own from Bitmap , and add a Disposed property that tracks whether the object has been disposed.
You would need to override the Dispose method to set the flag to true.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Not sure that would work, since the flag would be Disposed at the same time as the rest of it. At best, it would risk problems with consistency once the GC kicked in, wouldn't it?
He could get away with encapsulating a Bitmap, and Disposing that without disposing the outer object, but...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
You're right. I guess I didn't engage the brain before the fingers.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
On second thought, I thought the purpose of Dispose is to release unmanaged resources.
The managed memory of an object would remain valid until it goes out of scope, no?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|