Much as I’ll admit to some spittle-flecked indignation when it comes to Visual Studio 20-anything, it has largely been the development tool that has paid my mortgage and allowed me to eat biscuits and cake. But this one takes the biscuit, cake, mug of tea and plate.

I’m happily working away, writing code when suddenly find in files stops working with the wonderful message “No Files Were Found To Look In. Find Was Stopped In Progress” Ah it’s simple. I’ve obviously fiddled with the search options and not selected the file types to search in or something similar. Nope –  everything looks just fine.

Ah I know. Close devenv and start again. Nope – exactly the same.

So, off for a coffee and moan and someone says: “Press Ctrl+Scroll Lock a few times and it’ll be fine”. This sounds a bit Mornington Crecsent to me, but it worked.

Sometimes I wonder if I should just go back to using notepad.exe

Advertisements

Today seems to be the day for posting useful stuff on the blog. Actually, it’s just so I can quickly useful find bits of code I might need again.

So I’ve a got a web page that displays some text a user has entered that may contain URLs and I’d like them to be displayed as actual hyperlinks.

 

public string ConvertUrlsToLinks(string msg)
{
string regex = @"((www\.|(http|https|ftp|news|file)+\:\/\/)[_.a-z0-9-]+\.[a-z0-9\/_:@=.+?,##%&~-]*[^.|\'|\# |!|\(|?|,| |>|<|;|\)])";
Regex r = new Regex(regex, RegexOptions.IgnoreCase);
return r.Replace(msg, "$1").Replace("href=\"www", "href=\"http://www");
}

 

Not that this is is going to compete with a full blown keyword or tag service like Google offer, but I needed a very quick way to suggest keywords and tags as users filled out a blog form. There’s no fancy thesaurus or library of data, but it gives surprisingly good results. At least, it gives the user a few hints and ideas about what they should put in as a keywords.

public string GetKeywords(string text, int minCount, int minLength, string additionalWords)

{

string keywords = "";

Dictionary dict = getKeywords(text, minCount, minLength);

foreach (var entry in dict)

 

keywords += entry.Key + ",";

if (additionalWords.Length > 0)

keywords += additionalWords;

return keywords.Trim(',');

}

private Dictionary getKeywords(string text, int minCount, int minLength)

{

text = StripHTML(text);

text = StripCrap(text);

text = text.ToLower();

var stopWords = new string[] {"about","above","across","after","again","against","all","almost","alone","along","already","also","although","always","among","an","and","another","any","anybody","anyone","anything","anywhere","are","area","areas","around","as","ask","asked","asking","asks","at","away","back","backed","backing","backs","be","became","because","become","becomes","been","before","began","behind","being","beings","best","better","between","big","both","but","by","came","can","cannot","case","cases","certain","certainly","clear","clearly","come","could","did","differ","different","differently","do","does","done","down","down","downed","downing","downs","during","each","early","either","end","ended","ending","ends","enough","even","evenly","ever","every","everybody","everyone","everything","everywhere","face","faces","fact","facts","far","felt","few","find","finds","first","for","four","from","full","fully","further","furthered","furthering","furthers","gave","general","generally","get","gets","give","given","gives","go","going","good","goods","got","great","greater","greatest","group","grouped","grouping","groups","had","has","have","having","he","her","here","herself","high","high","high","higher","highest","him","himself","his","how","however","if","important","in","interest","interested","interesting","interests","into","is","it","its","itself","just","keep","keeps","kind","knew","know","known","knows","large","largely","last","later","latest","least","less","let","lets","like","likely","long","longer","longest","made","make","making","man","many","may","me","member","members","men","might","more","most","mostly","mr","mrs","much","must","my","myself","necessary","need","needed","needing","needs","never","new","new","newer","newest","next","no","nobody","non","noone","not","nothing","now","nowhere","number","numbers","of","off","often","old","older","oldest","on","once","one","only","open","opened","opening","opens","or","order","ordered","ordering","orders","other","others","our","out","over","part","parted","parting","parts","per","perhaps","place","places","point","pointed","pointing","points","possible","present","presented","presenting","presents","problem","problems","put","puts","quite","rather","really","right","right","room","rooms","said","same","saw","say","says","second","seconds","see","seem","seemed","seeming","seems","sees","several","shall","she","should","show","showed","showing","shows","side","sides","since","small","smaller","smallest","so","some","somebody","someone","something","somewhere","state","states","still","still","such","sure","take","taken","than","that","the","their","them","then","there","therefore","these","they","thing","things","think","thinks","this","those","though","thought","thoughts","three","through","thus","to","today","together","too","took","toward","turn","turned","turning","turns","two","under","until","up","upon","us","use","used","uses","very","want","wanted","wanting","wants","was","way","ways","we","well","wells","went","were","what","when","where","whether","which","while","who","whole","whose","why","will","with","within","without","work","worked","working","works","would","year","years","yet","you","young","younger","youngest","your","yours"};

var words = Regex.Replace(text, @"[,.?\/;:\(\)]", string.Empty).Split(' ');

var occurrences = words.Distinct().Except(stopWords).Select(w =>

new { Word = w, Count = words.Count(s => s == w) });

return occurrences.Where(wo => wo.Count >= minCount && wo.Word.Length >= minLength)

.ToDictionary(wo => wo.Word, wo => wo.Count);

}

 

minCount the minimum number of duplicate words to catch
minLength the minimum length of word to word on
additionalWords is a set of comma separated word you want tagged(!) to the end of the string. I just use this to force certain keywords and tags

So taking the content of this page (less the code snippet) like this:

string tags = GetKeywords(articletext, 2, 4, "dave");

results in:

“keywords,tags,minimum,word,dave” which isn’t a lot different from what WordPress generated for me automatically, so I used it for my post tags.

OO purists have long argued that switching on the type of an object by using some conjured up member enum is wrong. And I agree. Fundamentally, it’s nasty and you can satisfyingly waggle your finger at poor OO design.

However, sometimes things aren’t so easy and straightforward. I’m currently working with a complex financial trade class hierarchy that simply can’t be changed – it just wouldn’t be practical. I needed some new functionality that switched on an instance of the base class of the hierarchy. Ok, so it breaks all the rules, but at least it’s switching on a common base type and not completely unrelated types. Peter Hallam’s article describes the problems with a generalised type switch built into the language and why it’s not practical.

So what follows is stream of software design consciousness that touches on the relative casting performance of C# as vs. is, lambda functions, generics and fluent interfaces (method chaining) that achieves a solution.

Lets assume we have some simple class hierarchy. These classes do nothing, but demonstrate the principles involved. We’ll use these throughout the examples.


// Our base class
public class Trade
{
    public void TradeMethod()
    {
    }
}

public class GenericTrade : Trade
{
    public void GenericTradeMethod()
    {
    }
}

public class SwapTrade : Trade
{
    public void SwapTradeMethod()
    {
    }
}

public class SpotTrade : Trade
{
    public void SpotTradeMethod()
    {
    }
}

A first stab at switching on type might be like this:


public void doSomething(Trade trade)
{
    if (trade is GenericTrade)
    {
        GenericTrade genericTrade = trade as GenericTrade;
        genericTrade.GenericTradeMethod();
        // ....
        // ....
    }
    else
        if (trade is SwapTrade)
        {
            SwapTrade swapTrade = trade as SwapTrade;
            swapTrade.SwapTradeMethod();
            // ....
            // ....
        }
        else
            if (trade is SpotTrade)
            {
                SpotTrade spotTrade = trade as SpotTrade;
                spotTrade.SpotTradeMethod();
                // ....
                // ....
            }
            else
            {
                // Default actions
                // ....
                // ....
            }
}

Well it works, but it has a couple of problems.

  • C# offers the syntactically concise way to upcast and downcast using as and is. Unfortunately as Emilio Guijarro shows, the relative performance of ‘as’ vs ‘is’ when typecasting means ‘is‘ is pretty slow.
  • Somehow, the if…else.. If …else structure seams very clunky when there’s more than a few types.

To get around using the slow ‘is‘ is easy.


public void doSomethingElse(Trade trade)
{
    GenericTrade genericTrade = new GenericTrade();
    SwapTrade swapTrade = new SwapTrade();
    SpotTrade spotTrade = new SpotTrade();

    if (genericTrade as GenericTrade != null)
    {
        genericTrade.GenericTradeMethod();
        // ....
        // ....
    }
    else
        if (swapTrade as SwapTrade != null)
        {
            swapTrade.SwapTradeMethod();
            // ....
            // ....
        }
        else
            if (genericTrade as GenericTrade != null)
            {
                genericTrade.GenericTradeMethod();
                // ....
                // ....
            }
            else
            {
                // Default actions
                // ....
                // ....
            }
}

This requires an instance of each type, but the structure is even more horrible than before. So abandon that way of doing it. What we really need is something that is readable. Something like this would be ideal:


public void doSomething(Trade trade)
{
    switch (trade)
   {
      case GenericTrade:
            // ...
            // ...
            break;
      case SwapTrade:
            // ...
            // ...
            break;
       case SpotTrade:
            // ...
            // ...
            break;
        default:
            // ...
            // ...
            break;
      }
}

Bart De Swet’s article that describes a solution that yields a similar code structure. This is implemented using method extensions which is unnecessarily complicated, so I devised a similar solution using instance methods.

So here’s my take on a switch class – I’ve called it SwitchOnType for clarity:


public class SwitchOnType<T1>
{
    bool _break = false;
    private T1 _object;

    public SwitchOnType(T1 obj)
    {
        _object = obj;
    }

    public SwitchOnType<T1> Case<T2>(Action<T2> action) where T2 : class
    {
        if (_break == false)
        {
            T2 t = _object as T2;
            if (t != null)
            {
                action(t);
                _break = true;
            }
        }
        return this as SwitchOnType<T1>;
    }
    public void Default<T2>(Action<T2> action) where T2 : class
    {
        if (_break == false)
        {
            T2 t = _object as T2;
            if (t != null)
                action(t);
        }
    }
}

And here’s how it’s used with our class hierarchy example:


public void doSomething(Trade trade)
{
    new SwitchOnType<Trade>(trade)
        .Case<GenericTrade>(genericTrade =>
        {
            // It's a GenericTrade
            genericTrade.GenericTradeMethod();
            // ...
            // ...
        })
        .Case<SwapTrade>(swapTrade =>
        {
            // It's a SwapTrade
            swapTrade.SwapTradeMethod();
            // ...
            // ...
        })
        .Case<SpotTrade>(spotTrade =>
        {
            // It's a SpotTrade
            spotTrade.SpotTradeMethod();
            // ...
            // ...
        })
        .Default<Trade>(t =>
        {
            // Default actions
            t.TradeMethod();
        });
}

Although there’s a few extra {‘s and )’s, the structure is close to the ideal. This is mainly possible using method chaining (also known as fluent interfaces), by returning this (well a genericized this) in the case method and passing the code to be executed if the case test succeeds as a lambda function. Note if none of the Case methods succeeds, the Default method will get called. If you want to know more about fluent interfaces read Martin Fowler’s article.

So just accept that sometimes you have no choice and have to accept that it’s right to do what’s wrong – is that software or life. Or both.

Intrigue is curious thing, much as curiosity is intriguing. What drives it? Mostly just needing to know something for no other reason than wanting to know itself – curious indeed. 

So why would I really be bothered to know what WindowsFormsSyncronizationContext does under the hood? Well dear bleader (if someone who write blogs is a blogger, maybe someone who reads blogs is a bleader) I had my suspicions, but I just needed to find out.

SynchronizationContext and it’s derivatives was introduced in .NET 2.0 as simple .NET language construct to allow a non-GUI thread to call methods on a GUI control. Previously, code had to be written to perform the InvokeRequired, BeginInvoke, Invoke dance and as has been discovered, this has problems and  can have you chasing nasty bugs.

In https://davebrooks.wordpress.com/2007/02/12/begininvoke-the-land-of-confusion/ I discussed BeginInvoke for delegates and controls, some issues and how they worked under the hood.

As I said before, I was suspicious that WindowsFormsSynchronizationContext worked pretty much the same way. And Lo, with a bit of windows message spying on a simple test app, my suspicions were confirmed. WindowsFormsSynchronizationContext.Post() and .Send() end up using PostMessage with registered windows messages, presumably using BeginInvoke and Invoke respectively to push the control method call onto the main GUI thread.  However, it does make the code earlier to write and as we all know, less code means less bugs.

Now to find out what happens in the Freemasons. I’m just curious you understand.

I’ve been meaning to get around to sorting out the plethora of App.config in a large, multi project C# solution, but it wasn’t anywhere near the top of the pile of problems that needed solving. I just keep hacking values into the *.exe.config file after the build to make things work.

In a spare (and rare) 20 minutes, while drinking a coffee, I thought I’d have a quick look and discovered a really simple solution. For some reason this technique had completely passed me by. Imagine you’ve got a C# solution made up of 3 projects which build into 3 separate executables, each requiring a common config file. If you have simply added a config file to each project and try to keep them in sync you quickly end up in config hell. So rather that add a new config file to each project, simply create one in one of the projects and then link it in the others.

Here’s how, in our imaginary 3 project solution

Solution
     Project1
     Project2
     Project3

  • Right click on Project1 and select Add->New Item->Application Configuration File and it will create a the file App.config in Project1.
  • Right click on Project2 and select Add->Existing Item and browse to Project1’s App.config file, but don’t hit the Add button. Select the Add button drop down and select Add as link.
  • Repeat for Project3

So now when you open any of the projects App.config files you will be using the same file. More importantly, when you build the solution, each projects bin/Debug (Release) directory will have it’s own, but identical copy of the config file (Project*.exe.config) leaving you the freedom to deploy the executables with their own or a common config file. Essentially, building the solution duplicates the config files from a single master version.

Itch successfully scratched.

Having just had another article published on codeproject, I am reminded yet again how much I miss many of the features of C++ when I’m coding in C#. There’s no denying C# is a very productive language, but C++ techniques I have used and taken for granted just aren’t possible.Generics are a case in point. I constantly feel C# is wanting to hold my hand while crossing the programming road. Generics and C++ templates are not the same thing – the design goals are very different. C# generics are like classes that have a type parameter and everything (pretty much) happens at runtime and C++ templates are just macros that look like classes and it all comes together at compile (and maybe link) time.

If all you do with templates is type safe collections, this is probably not an issue and generics could be considered a safer approach, but it is very limiting. In the SyncInvoker article I use template metaprogramming to achieve code reusability. More accurately I guess this comes under the heading of generic programming so I avoid having the re-write sections of similar code that have minor variations. I guess I’m just lazy.

Template metaprogramming allows the programmer to concentrate on architecture and delegate to the compiler the generation of any implementation required by client code. With template metaprogramming you can create truly generic code – a smaller codebase and better maintainability. However, the syntax and idioms of template metaprogramming are esoteric compared to conventional C++ programming sometimes even the most trivial, template metaprogramming can be very difficult to understand.