The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,854 other subscribers

Archive for the ‘C#’ Category

.NET/C# – How to create a file and its parent directories in one method call? (via: Stack Overflow)

Posted by jpluimers on 2012/12/18

Ever since .NET 1 there has been no built-in way to create a file including all its parent directories.

Hence small FileHelper class far below.

The fundament of the class is this CreateUnderlyingDirectory method, that uses System.IO.Path.GetDirectoryName to obtain the parent directory of a path, and then System.IO.Directory.CreateDirectory to create it (and any parent directories) if needed.

        public static void CreateUnderlyingDirectory(string path)
        {
            string directoryPath = Path.GetDirectoryName(path);
            Directory.CreateDirectory(directoryPath); // NOP if it exists, will create all parent directories if not
        }

A few helper methods get you a StreamWriter either empty/appended, or always empty Read the rest of this entry »

Posted in .NET, .NET 3.5, .NET 4.5, C#, C# 2.0, C# 3.0, C# 4.0, C# 5.0, Development, Software Development | Leave a Comment »

.NET/MSBuild: A solution for Skipped Build: Project: MyProject, Configuration: Debug Any CPU; Project not selected to build for this solution configuration

Posted by jpluimers on 2012/12/12

One of our solutions would not completely build.

An console application that was hardly used, was not built.

No warnings or hints in the “Error List”.

This is what the build log would show:

------ Skipped Build: Project: App404.UI, Configuration: Debug Any CPU ------
Project not selected to build for this solution configuration
========== Build: 21 succeeded or up-to-date, 0 failed, 1 skipped ==========

None of the suggestions at the Stack Overflow question visual studio 2005: skipping builds for unknown reason? would work (not even running msbuild with the highest verbosity level, you get so much information that it is impossible to weed the useful from the useless information).

Luckily, About | WishMesh pointed me in the right direction: inspect your solution file for anomalies. Read the rest of this entry »

Posted in .NET, C#, C# 4.0, Development, Software Development, Visual Studio 11, Visual Studio 2005, Visual Studio 2008, Visual Studio 2010, Visual Studio and tools | Leave a Comment »

C#: any c# – .NET Enumeration allows comma in the last field – Stack Overflow

Posted by jpluimers on 2012/12/06

Thanks Nick Craver for answering this on StackOverflow.

Array initializers can be specified in field declarations (§17.4), local variable declarations (§15.5.1), and
array creation expressions (§14.5.10.2).

The array initializer can end in a comma, which makes some things way easier (boy, I wish I had this in other programming languages).

From Nick’s answer:

It has no special meaning, just the way the compiler works, it’s mainly for this reason:

[FlagsAttribute]
public enum DependencyPropertyOptions : byte
{
Default = 1,
ReadOnly = 2,
Optional = 4,
DelegateProperty = 32,
Metadata = 8,
NonSerialized = 16,
//EnumPropertyIWantToCommentOutEasily = 32
}
[/language]By comment request: This info comes straight out of the ECMA C# Specification (Page 363/Section 19.7)

“Like Standard C++, C# allows a trailing comma at the end of an array-initializer. This syntax provides flexibility in adding or deleting members from such a list, and simplifies machine generation of such lists.”

–jeroen

via c# – .NET Enumeration allows comma in the last field – Stack Overflow.

Posted in .NET, C#, C# 1.0, C# 2.0, C# 3.0, C# 4.0, C# 5.0, C++, Delphi, Development, Java, JavaScript/ECMAScript, PHP, Software Development, VB.NET | 5 Comments »

.NET/C#/WinForms: small code snippet to enable Ctrl-A for select all in a single/multi-line TextBox

Posted by jpluimers on 2012/12/04

WinForms does not automatically enable Ctrl-A as “Select All” action.

The below code snippet works when you bind it to the KeyDown event of a TextBox (actually the event is on Control).

The e.SuppressKeyPress = true suppresses the bell sound in a multiline TextBox, as e.Handled = true won’t.

        private void textBox_KeyDown_HandleCtrlAToSelectAllText(object sender, KeyEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (null != textBox)
            {
                if (e.Control && e.KeyCode == Keys.A)
                {
                    textBox.SelectAll();
                    e.SuppressKeyPress = true;
                }
            }
        }

–jeroen

Posted in .NET, .NET 1.x, .NET 2.0, .NET 3.0, .NET 3.5, .NET 4.0, .NET 4.5, C#, C# 1.0, C# 2.0, C# 3.0, C# 4.0, C# 5.0, Development, Software Development | Leave a Comment »

.NET/C# LINQ gem: How to check if a char in a list of characters (via Stack Overflow)

Posted by jpluimers on 2012/11/21

Often when comparing characters with a list of characters, that list does not consist of consts.

It if were, you could make a switch statement:

                    switch (item)
                    {
                        case '/':
                        case '\\':
                        case ';':
                            addSeparator(separatorsUsed, item);
                            break;
                    }

But reality is that you cannot do things like this:

                    switch (item)
                    {
                        case Path.AltDirectorySeparatorChar: // Error: A constant value is expected
                        case Path.DirectorySeparatorChar:
                        case Path.PathSeparator:
                            addSeparator(separatorsUsed, item);
                            break;
                    }

However, you can perform a small trick and use LINQ to write some pretty elegant code based on Contains.

                    char[] pathSeparators = { Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.PathSeparator };
                    // LINQ: http://stackoverflow.com/questions/1818611/how-to-check-if-a-char-in-a-char-array/1818635#1818635
                    if (pathSeparators.Contains(item))
                        addSeparator(separatorsUsed, item);

The LINQ logic has the logic backwards (you can think of it like “item in pathSeparators”, but it is far easier to read than this:

                    if ((item == Path.AltDirectorySeparatorChar) || (item == Path.DirectorySeparatorChar) || (item == Path.PathSeparator))
                        addSeparator(separatoseparatorsUsedrsInUse, item);

Full source of a demo application: Read the rest of this entry »

Posted in .NET, .NET 3.5, .NET 4.5, C#, C# 3.0, C# 4.0, C# 5.0, Development, LINQ, Software Development, Visual Studio 11, Visual Studio 2008, Visual Studio 2010, Visual Studio and tools | 2 Comments »

.NET/C# duh moment of the day: “A char can be implicitly converted to ushort, int, uint, long, ulong, float, double, or decimal (not the other way around; implicit != implicit)”

Posted by jpluimers on 2012/11/20

A while ago I had a “duh” moment while calling a method that had many overloads, and one of the overloads was using int, not the char I’d expect.

The result was that a default value for that char was used, and my parameter was interpreted as a (very small) buffer size. I only found out something went wrong when writing unit tests around my code.

The culprit is this C# char feature (other implicit type conversions nicely summarized by Muhammad Javed):

A char can be implicitly converted to ushort, int, uint, long, ulong, float, double, or decimal. However, there are no implicit conversions from other types to the char type.

Switching between various development environments, I totally forgot this is the case in languages based on C and Java ancestry. But not in VB and Delphi ancestry  (C/C++ do numeric promotions of char to int and Java widens 2-byte char to 4-byte int; Delphi and VB.net don’t).

I’m not the only one who was confused, so Eric Lippert wrote a nice blog post on it in 2009: Why does char convert implicitly to ushort but not vice versa? – Fabulous Adventures In Coding – Site Home – MSDN Blogs.

Basically, it is the C ancestry: a char is an integral type always known to contain an integer value representing a Unicode character. The opposite is not true: an integer type is not always representing a Unicode character.

Lesson learned: if you have a large number of overloads (either writing them or using them) watch for mixing char and int parameters.

Note that overload resolution can be diffucult enough (C# 3 had breaking changes and C# 4 had breaking changes too, and those are only for C#), so don’t make it more difficult than it should be (:

Below a few examples in C# and VB and their IL disassemblies to illustrate their differnces based on asterisk (*) and space ( ) that also show that not all implicits are created equal: Decimal is done at run-time, the rest at compile time.

Note that the order of the methods is alphabetic, but the calls are in order of the type and size of the numeric types (integral types, then floating point types, then decimal).

A few interesting observations:

  • The C# compiler implicitly converts char with all calls except for decimal, where an implicit conversion at run time is used:
    L_004c: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(char)
    L_0051: call void CharIntCompatibilityCSharp.Program::writeLineDecimal(valuetype [mscorlib]System.Decimal)
  • Same for implicit conversion of byte to the other types, though here the C# and VB.NET compilers generate slightly different code for run-time conversion.
    C# uses an implicit conversion:
    L_00af: ldloc.1
    L_00b0: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(uint8)
    L_00b5: call void CharIntCompatibilityCSharp.Program::writeLineDecimal(valuetype [mscorlib]System.Decimal)
    VB.NET calls a constructor:
    L_006e: ldloc.1
    L_006f: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
    L_0075: call void CharIntCompatibilityVB.Program::writeLineDecimal(valuetype [mscorlib]System.Decimal)

Here is the example code: Read the rest of this entry »

Posted in .NET, Agile, Algorithms, C#, C# 1.0, C# 2.0, C# 3.0, C# 4.0, C# 5.0, C++, Delphi, Development, Encoding, Floating point handling, Java, Software Development, Unicode, Unit Testing, VB.NET | 1 Comment »

Some notes on finding the cause of a .NET app generating a “application has generated an exception that could not be handled”

Posted by jpluimers on 2012/11/15

A while ago, one of the users at a client got an error in a .NET 1.1 app of which the sources were not readily available:

“application has generated an exception that could not be handled”

I think it is a e0434f4d  exception.

This particular site has very strict rules about what you can and cannot do as a developer. Which means that on a production system, you basically cannot do anything.

A few links that should help me finding the solution, and escalate far enough upstream to get someone with local admin rights to assist me:

If WinDbg is allows to be ran, these should help me:

–jeroen

Posted in .NET, .NET 1.x, .NET 2.0, .NET 3.0, .NET 3.5, .NET 4.0, .NET 4.5, C#, C# 1.0, C# 2.0, C# 3.0, C# 4.0, C# 5.0, Development, Software Development | Leave a Comment »

Interesting: Visual Studio Project Renamer | ComVisible

Posted by jpluimers on 2012/11/14

Over the course of development time, each suite of projects is bound to get some renames.

Doing that from the Visual Studio IDE is a pain, so I was glad to find Visual Studio Project Renamer by ComVisible.

Though it only supports C# and VB.NET projects (so no solution rename or rename of F#, Database or Reporting Service projects, nor stuff outside of the Microsoft realm like Prism).

These Just geeks: Renaming a Visual Studio Project link led me to the project.

Renaming solutions still is largely a manual operation as it involves renaming directories. You have to re-add some (sometimes all) projects later where this tool can come in handy: CoolCommands by SharpToolbox.

–jeroen

via:

Posted in .NET, C#, C# 2.0, C# 3.0, C# 4.0, C# 5.0, Development, F#, Prism, Software Development, VB.NET, Visual Studio and tools | Leave a Comment »

.NET/C#: Cleaning up path names with invalid characters (via: validation – C# Sanitize File Name – Stack Overflow)

Posted by jpluimers on 2012/11/13

Thanks Andre for this cleanup code:

To clean up a file name you could do this

private static string MakeValidFileName(string name)
{
string invalidChars = Regex.Escape( new string( Path.GetInvalidFileNameChars() ) );
string invalidReStr = string.Format( @"[{0}]+", invalidChars );
return Regex.Replace( name, invalidReStr, "_" );
}

Next to GetInvalidFileNameChars, you have GetInvalidPathChars.

–jeroen

via: validation – C# Sanitize File Name – Stack Overflow.

Posted in .NET, C#, Development, Software Development | 2 Comments »

.NET/C#: Drives, Directories, Paths and Filenames in Windows is hard, let alone cross platform (: via: .net – Why Path.Combine doesn’t add the Path.DirectorySeparatorChar after the drive designator? – Stack Overflow)

Posted by jpluimers on 2012/11/08

Handling names of drives and paths (directories, filenames) is hard in Windows, as both C:myfile.ext and C:\myfile.ext are valid – but potentially different – filenames, C is a valid driveletter, C: and C:\ are valid – but also potentially different – directory names.

This leads into confusion as how Path.Combine behaves.

Part of the confusion comes from the meaning of the absence or presence of the leading DirectorySeparatorChar as explained by user Peter van der Heijden:

C:filename is a valid path and is different from C:\filename. C:filename is the file filename in the current directory on the C: drive whereas C:\filename is the file filename in the root of that drive. Apparently they wanted to keep the functionality of refering to the current directory on some drive.

This behaviour is described here in MSDN

Another oddity is that Path.Combine will only use the drive portion of the left argument when the right argument contains an absolute path.

If you understand the above, then dealing with cross platform directory and path separators, spaces in filenames and UNC path names are peanuts (:

–jeroen

via: .net – Why Path.Combine doesn’t add the Path.DirectorySeparatorChar after the drive designator? – Stack Overflow.

Posted in .NET, C#, C# 2.0, C# 3.0, C# 4.0, C# 5.0, Development, Software Development | Leave a Comment »