Tuesday, June 16, 2015

How to launch an elevated prompt

Here's a trick to launch an elevated prompt or run any app as Administrator elevated even from a non-elevated command prompt.

Use 'pseudo'.   It's kinda like 'sudo'

See https://github.com/kasajian/pseudo

Friday, May 1, 2015

Alternative to mocking static methods in C#

Curious what you guys think of this as an alternative to mocking static methods in C#?
Here's a a simply way to mock static methods without a mocking framework.

Say you have code like this:
        class Math
        {
            public static int Add(int x, int y)
            {
                return x + y;
            }

You want to "mock" the Add method, but you can't. Change the above code to this:

        class Math
        {
            public static Func Add = (x, y) =>
            {
                return x + y;
            };

Existing client code doesn't have to change (maybe recompile), but source stays the same.

Now, from the unit-test, to change the behavior of the method, just reassign an in-line function to it:
    [TestMethod]
    public static void MyTest()
    {
        Math.Add = (x, y) =>
        {
            return 11;
        };dada

Put whatever logic you want in the method, or just return some hard-coded value, depending on what you're trying to do.

This may not necessarily be something you can do each time, but in practice, I found this technique works just fine.

Another thing to keep in mind.   When you set the static variable like that, you should undo it when the test is complete.   One way to do that is to re-run the class's static initializer. 

 Example:
    typeof(SomeClassName).TypeInitializer.Invoke(null, null);

Wednesday, March 18, 2015

Favorite Day-of-Week calculation

/* 0 = Sunday, 1 <= m <= 12, y > 1752 or so */
int dayofweek(int y, int m, int d)
{
    static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
    y -= m < 3;
    return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}

Wednesday, January 28, 2015

A slight-of hand with .NET Lazy

The following is an example of a better way to read a value from a C# dictionary.

In C#/.NET, you will get an exception if you specify an non-existent key when attempting to read a value from a Dictionary.   The workaround is to call the TryGetValue method, which is awkward because of the out parameter, and the requirement of the additional variable declaration (< C#6).

Sometimes the behavior that you want is to get a null or 0 value when using an invalid key.   Other times you want to simply test the returned value to see if actually has a value, similar to Option/Maybe idiom in other languages.

Because of the extensible nature of C#, you can kinda have your cake an eat it to.   There's multiple ways to solve this problem, and some cool functional libraries have this built in (such as https://github.com/louthy/language-ext ), but with some slight-of hand, you can actually re-purpose the .NET built-in Lazy class to do this for you.

A Lazy object is an object that holds another object (or value), but it may be empty.  The reason it exists is for "memoization", in that, the Lazy object starts out empty, and then later, it may be filled with a value.

But no is stopping you from using Lazy as a way to indicate an optional value.   The following is an extension to IDictionary called GetValue.  When called with an existing key, it returns a Lazy object containing the value.   If the key does not exist, it returns an empty Lazy object.   You just have to call IsValueCreated on the Lazy object to determine if the value exists.   Alternatively, you can just use the .Value property and use the type's default value, such as 0 or null, when the key doesn't exist.  Depending on what you're doing, that may be what you want.

Either way, you don't have to use TryGetValue

References:

http://programmers.stackexchange.com/questions/159096/return-magic-value-throw-exception-or-return-false-on-failure/264516#264516

http://www.extensionmethod.net/csharp/idictionary/idictionary-getvalue

Wednesday, January 21, 2015

C# Dictionary to XML

Do you have a string dictionary in .NET code (C#) that want to write out to disk in nicely formatted XML?

A single line of text will do this:

new XElement("root", d.Select(
    kv => new XElement(kv.Key, kv.Value)))
        .Save(filename, SaveOptions.OmitDuplicateNam
espaces);


To read the XML file back later into a dictionary, is another single line:

var d = XElement.Parse(File.ReadAllText(filename))
    .Elements()
    .ToDictionary(k =>
        k.Name.ToString(),
        v => v.Value.ToString
());

That's it!

Monday, January 19, 2015

Easily Zip just the source of a Visual Studio project

When playing around, creating new Visual Studio projects such as a weekend project, you want an easy way to zip up my source and not worry about .pdb, obj/bin files, etc. files.
The .gitignore file is created when you create a Visual Studio project with the "Create new Git repository" selected.
You don't need to use pkzip because Git has the archiving feature built-in.  Just type:
git archive -o all.zip HEAD
and it will create all.zip of the latest source, without any of the stuff you don’t want in the .zip file like bin, obj, exes, nuget assemblies, etc.

Sunday, January 18, 2015

Double click file to run a PowerShell script

Typically, you cannot double click on a PowerShell script (.ps1 file) and have it automatically run, like you could with a batch file (.bat or .cmd). This is a good thing because someone may accidentally run something that was not meant to be run.

But what if you need to have someone run a PowerShell script and you just want them to double click a shortcut of some sort to make it happen.

The trick is to create a batch file that invokes the PowerShell. If you give the batch file and PowerShell script the same base name, then the batch file content doesn't have to change:


@echo off
pushd "%~d0"
pushd "%~dp0"
powershell.exe -sta -c "& {.\%~n0.ps1 %*}"
popd
popd

So, for instance, if you wish to run a PowerShell script called xyz.ps1, just create xyz.bat with the above content.

That's it!


By the way, the two pushd/popds are necessary in case the user's CDs is on a different drive. Without the outer set, the CD on the drive with the script will get lost.