This blog has, IMO, some great resources. Unfortunately, some of those resources are becoming less relevant. I'm still blogging, learning tech and helping others...please find me at my new home on http://www.jameschambers.com/.
Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Thursday, March 3, 2011

Extension Methods for Converting ints and bools

I was recently working on a chunk of code where I had three different scenarios for conversion.  With two external libraries (something I couldn’t change) and this not being a big enough project (so not worth a facade) as driving factors I rolled a couple of simple to use extension methods.

The Code

I won’t lollygag here too much.  You need a namespace and static class name that work for your (they’re more-or-less irrelevant in the grander scheme), and a couple of static methods.

namespace ExtensionMethods
{
    public static class Extensions
    {
        public static bool ToBool(this int i)
        {
            return i == 0 ? false : true;
        }

        public static int ToInt(this bool b)
        {
            return b ? 1 : 0;
        }

        public static int ToInt(this bool? b)
        {
            return b.HasValue ? (b.Value ? 1 : 0) : 0;
        }
    }
}

Basically, we’re just using a tertiary operation to decide which value is appropriate to use in each of the contexts.

The third method is there to help out with nullable boolean values.  This was handy in my case, not sure how many people would need this.

Tuesday, April 27, 2010

Resolving LINQ Error: Missing Query Pattern Implementation

There are a couple of errors that I have come up in working with LINQ and LINQ to SQL that have common roots.  There are a couple of easy fixes when you run into the following error:

Could not find an implementation of the query pattern for source type <SomeType>.

You will also receive some further information about the error, usually along the lines of one of the following:

  • 'Where' not found.
  • 'Select' not found.

Fix 1: LINQ Using Missing

This one is easy: just make sure you have the following using statement in your class file:

image

Fix 2: Got Members?

Use the correct member of the object you are performing a query on, and make sure you’re not intending to use a property of mehod of that type.

For Example, where _dc is a DataContext object for LINQ to SQL, I have absent-mindedly forgotten the table reference in the query:

image

The above should be written as follows to avoid the query pattern implementation error:

image

That one can be a little more tricky because – especially if you’re coding late – the compiler error doesn’t really lead you to a ‘I missed a property reference’ with that error.

Fix 3: Wrong Type

Make sure you are trying to query an object that works with LINQ.  Specifically, LINQ to objects will need to have an implementation of the IEnumerable interface in the object that it is trying to query.

If you run into something that is called GetNameList, but it returns a delimited string instead of (the expected) List<string>, you can still query it after you take a simple step and do the split:

image

…and those are the most common ways to solve issues around the missing implementation of the query pattern for ‘x’ problem.

Thursday, June 4, 2009

Quick and Dirty Active Directory with c#

If you just want to grab some properties off a list of well-known entities in an Active Directory group, here’s some code to help you achieve that:

DirectoryEntry group = new DirectoryEntry(LDAP://CN=yourgroup,CN=users,DC=domain,DC=ca);
object members = group.Invoke("Members", null);
foreach (object member in (IEnumerable)members)
{
DirectoryEntry entry = new DirectoryEntry(member);

Console.WriteLine(entry.Name);
Console.WriteLine(" {0}", entry.Properties["telephoneNumber"].Value);
Console.WriteLine(" {0}", entry.Properties["displayname"].Value);
}


If you know the data is in there, but you’re not sure what it is called in Active Directory, you can change that foreach loop to the following to dump everything you’re allowed to see.  This is pretty trivial in any .Net language, and the Active Directory properties are easy to work with (they’re just a collection):



foreach (object member in (IEnumerable)members)
{
DirectoryEntry entry = new DirectoryEntry(member);
foreach (string prop in entry.Properties.PropertyNames)
{
Console.WriteLine(" {0}: {1}", entry.Properties[prop].PropertyName, entry.Properties[prop].Value);
}
break;
}



I added the break in there so it just dumps the properties of the first entity in the list. 



Obviously, you’ll want to change the “yourgroup”, “domain” and “com” to whatever your server is configured to use.  Then, you’ll be well on your way to extracting properties for users stored in Active Directory.

Monday, May 11, 2009

Getting at the Text of a ComboBox in WPF

I am writing a small wrapper for WPF’s ComboBox and want to hook up (optionally) a delegate that filters the list of items, based on what the user has typed already into the text box portion of the control.

I have achieved this with the help of Mole and the FindName method on the Template object.

TextBox input = ((TextBox)comboBox1.Template.FindName("PART_EditableTextBox",comboBox1));
input.TextChanged += new TextChangedEventHandler(input_TextChanged);

FindName allows us to walk across a templated control and search for a child element by the name we pass in.  This allows us to get at some of the innards for some of the existing controls and, in my case as above, attach to events or check properties and the like.

Tuesday, May 5, 2009

Slightly Better Version

Last week I posted a function to convert an IP address to its decimal value using c#.

I have a mildly better approach, though by better, admittedly, I really just mean “I’m using some new stuff from the current version of c#”.

It occurred to me that in place of the anonymous delegate I could just as easily use a lambda expression, therefore we end up with this approach:

private static string IpToDecimal(string ipAddress)
{
// split up the IP into octets and prep our string builder
List<string> octets = new List<string>(ipAddress.Split('.'));
long decIP = 0;
int shift = 3;

// loop through the octets and compute the decimal version
octets.ForEach(octet => { decIP += long.Parse(octet) << (shift * 8); shift--; });
return decIP.ToString();
}



Now, if you wanted to, you could really use var instead of List<string> and you could likely inline the initialization, but that ends up unreadable.



HOWEVER if you are adamant about using new things, like LINQ, lambda expressions and the language features of c# to convert this bad boy over, you can do it!



I just wouldn’t likely throw this code at the rookie…



private static string IpToDecimal2(string ipAddress)
{
// need a shift counter
int shift = 3;

// split and loop through the octets
var octets = ipAddress.Split('.').Select(p => long.Parse(p));
return octets.Aggregate(0L, (total, octet) =>
(total + (octet << (shift-- * 8)))).ToString();
}



This is actually cool because it’s really only three lines of code.  A couple of things to note:




  1. Using LINQ we are able to parse out the string bits and convert the octets to longs with the Select method.


  2. I’m using the Aggregate method and passing in a seed of 0, which I type with L so that the compiler doesn’t see it as an int.


  3. total is used to keep the running track; octet is the parameter passed in from the octets collection.


  4. shift is decremented each pass as we walk across the octets.

Friday, May 1, 2009

Oh…Brainwaves!

Just occurred to me that you can also fairly easily convert the IP if you shift the values as you walk across the octets. 

Here’s a simpler version of the same method.  I’m not using any of the formatting, but I still employ the anon delegate on the generic list. 

private static string IpToDecimal(string ipAddress)
{
// split up the IP into octets and prep our string builder
List<string> octects = new List<string>(ipAddress.Split('.'));
long decIP = 0;
int shift = 3;

// loop through the octets and compute the decimal version
octects.ForEach(delegate(string value)
{ decIP += long.Parse(value) << (shift * 8); shift--; });

return decIP.ToString();
}



Here’s a bit of trivia on IP addresses and the internet: it’s all a lie.  You don’t actually “go” to a web site by name; that’s just what you type.  A web site end point is actually a port on an IP address.  Typically HTTP runs on port 80, so that’s assumed by the http prefix.  So, you can go to http://www.google.com, or you can go to http://209.85.171.100 and it’s the same thing.  What’s cool is that if you take that IP and convert it to decimal, such as http://3512052580, you can also go to that address and see the Google home page. Depending on your browser, it might convert that 3512052580 to the IP address for you, but it all goes to the same place.



Here’s how that code works:




  • Using the string.Split function and a character ‘.’ we break apart the list of octets from the IP address into a generic list of strings.  string.Split returns an array, which we can pass into the constructor of the List<T>.


  • Quickly, we create a variable to hold our result, then a counter to help us shift the bits.


  • Next, we ‘walk’ across the list using the ForEach method.  This method can accept a delegate to an existing function or an anonymous delegate in-line.


  • We tell the compiler that we want the in-line version by creating a code block {…} that accepts a string parameter called value.


  • Each octet is passed into the method, which, in turn, shifts the value 8 bits (times the number in our shift counter) and adds it to our result.  The first octet needs to be shifted 24 bits (3 bytes), the second 16 and the third 8.  The last octet does not need to be shifted (0 * 8 = 0) so it is evaluated to its decimal value and added to the result.



Easy peasy lemon squeezy.  And that’s how you use .Net – not just loops and old-school brute force – to convert an IP address to a decimal.



Hrm…actually…I guess I’m returning that as a string…

Converting an IP Address to Decimal

I am working through some interop code to manage a DHCP server from c#, which requires that I pass in IP addresses as their decimal value.

There are a number of ways to do this with loops and conversions and such but I wanted to write a way that actually uses some of the features of the .Net Framework.

This is a good example of using an anonymous delegate for iterating through a generic list (using the ForEach method) and building a hexadecimal string.  I use a simple formatting syntax to pad the lower-value bytes as required and then parse the entire string to get our decimal value.

private static string IpToDecimal(string ipAddress)
{
   
// split up the IP into octets and prep our string builder
   
List<string> octets = new List<string>(ipAddress.Split('.'));
    StringBuilder ipAsHex = new StringBuilder();

   
// loop through the octets and build up a hexidecimal string
   
octets.ForEach(delegate(string value)
    { ipAsHex.AppendFormat("{0:X2}", int.Parse(value)); });

   
// convert the hex to decimal and return
   
long decimalIP = long.Parse(ipAsHex.ToString(), NumberStyles.HexNumber);
    return decimalIP.ToString();
}

Thursday, April 30, 2009

Immediately Useful - BB>187

There is a part of a web admin console that we have that displays a MAC address of a device, which our network admin routinely punches in value by value into Calculator and converts it to a decimal format:

  AC:0F:BB:EF:01:CE

…and that becomes:

172.15.187.239.1.206

He has to do that because there is another utility that expects the decimal format of the MAC address.

AND, this has to be done each time we add a new device/customer/end point on our network.

I am using c# to convert the MAC address to decimal in this example.  .Net provides some quick-and-easy ways to convert from hex to decimal and this is ideal when converting a MAC address.

There are a number of approaches on how to solve this kind of issue, but I chose one that doesn’t require (much of) a user interface.  The only visible aspect of the program is a task tray icon that, when double-clicked, converts the contents of the clipboard from hex to decimal.

I chose this approach because, for the most part, we’re dealing with one (or few) of these conversions at a time.  He can copy, double-click and paste into the other app without having to introduce a third, windowed interface into the mix.

Here’s the meat of the method that does the work:

 

try
{
// grab whatever's on the clipboard
// and try to break it apart
string input = Clipboard.GetText();
string[] parts = input.Split(':');

// convert the data to integers
// and build a string
StringBuilder sb = new StringBuilder();
foreach (string part in parts)
{
sb.Append(int.Parse(part, NumberStyles.AllowHexSpecifier));
sb.Append(".");
}

// need to drop that last . from the
// string and set the clipboard
string result = sb.ToString();
Clipboard.SetText(result.Substring(0, result.Length - 1));
}
catch (Exception)
{
// nothing fancy here, anything goes
// wrong and we bail...
Clipboard.SetText("Hrm...Bad data...");
}



Put that into a double-click event handler for a NotifyIcon and you’re sailing.