Tag archive for 'csharp'

10
Apr

Using LINQ to foreach over an enum in C#

I can't be the only person in the world who wants to foreach over the values of an enum otherwise Enum.GetValues(Type enumType) wouldn't exist in the framework. Alas it didn't get any generics love in .NET 2.0 and unhelpfully returns an array.

Thanks to the power of LINQ you can do this:

foreach(CustomerTypes customerType in Enum.GetValues(typeof(CustomerTypes)).Cast<CustomerTypes>())

That is okay, but this is more concise:

foreach(CustomerTypes customerType in Enums.Get<CustomerTypes>())

The tiny class to achieve that is, of course:

using System.Collections.Generic;
using System.Linq;

public static class Enums {
	public static IEnumerable<T> Get<T>() {
		return System.Enum.GetValues(typeof(T)).Cast<T>();
	}
}

Great.

[)amien

24
Nov

Calculating Elf-32 in C# and .NET

Because you can never have enough hashing algorithms at your disposal this one is compatible with the elf_hash function that forms part of the Executable and Linkable Format.

using System;
using System.Security.Cryptography;

public class Elf32 : HashAlgorithm
{
	private UInt32 hash;

	public Elf32()
	{
		Initialize();
	}

	public override void Initialize()
	{
		hash = 0;
	}

	protected override void HashCore(byte[] buffer, int start, int length)
	{
		hash = CalculateHash(hash, buffer, start, length);
	}

	protected override byte[] HashFinal()
	{
		byte[] hashBuffer = UInt32ToBigEndianBytes(hash);
		this.HashValue = hashBuffer;
		return hashBuffer;
	}

	public override int HashSize
	{
		get { return 32; }
	}

	public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
	{
		return CalculateHash(seed, buffer, 0, buffer.Length);
	}

	private static UInt32 CalculateHash(UInt32 seed, byte[] buffer, int start, int size)
	{
		UInt32 hash = seed;

		for (int i = start; i < size; i++)
			unchecked {
				hash = (hash << 4) + buffer[i];
				UInt32 work = (hash & 0xf0000000);
				if (work != 0)
					hash ^= (work >> 24);
				hash &= ~work;
			}
		return hash;
	}

	private byte[] UInt32ToBigEndianBytes(UInt32 x)
	{
		return new byte[] {
			(byte)((x >> 24) & 0xff),
			(byte)((x >> 16) & 0xff),
			(byte)((x >> 8) & 0xff),
			(byte)(x & 0xff)
		};
	}
}

[)amien

19
Nov

Calculating CRC-64 in C# and .NET

Seeing how the CRC-32 C# class I posted some time ago continues to get lots of Google hits I thought I'd post a CRC-64 version which will no doubt be far less popular being the more limited use. Again, do not use this as a secure message signature, it's really for backward compatibility with legacy systems.

Unlike the previous CRC-32 version this one uses a pre-generated constant (well, readonly) table as the generation code was quite slow.

using System;
using System.Security.Cryptography;

public class Crc64 : HashAlgorithm
{
	public const UInt64 DefaultSeed = 0x0;

	private static readonly UInt64[] table = new UInt64[] {
		0x0000000000000000L, 0x01b0000000000000L, 0x0360000000000000L,
		0x02d0000000000000L, 0x06c0000000000000L, 0x0770000000000000L,
		0x05a0000000000000L, 0x0410000000000000L, 0x0d80000000000000L,
		0x0c30000000000000L, 0x0ee0000000000000L, 0x0f50000000000000L,
		0x0b40000000000000L, 0x0af0000000000000L, 0x0820000000000000L,
		0x0990000000000000L, 0x1b00000000000000L, 0x1ab0000000000000L,
		0x1860000000000000L, 0x19d0000000000000L, 0x1dc0000000000000L,
		0x1c70000000000000L, 0x1ea0000000000000L, 0x1f10000000000000L,
		0x1680000000000000L, 0x1730000000000000L, 0x15e0000000000000L,
		0x1450000000000000L, 0x1040000000000000L, 0x11f0000000000000L,
		0x1320000000000000L, 0x1290000000000000L, 0x3600000000000000L,
		0x37b0000000000000L, 0x3560000000000000L, 0x34d0000000000000L,
		0x30c0000000000000L, 0x3170000000000000L, 0x33a0000000000000L,
		0x3210000000000000L, 0x3b80000000000000L, 0x3a30000000000000L,
		0x38e0000000000000L, 0x3950000000000000L, 0x3d40000000000000L,
		0x3cf0000000000000L, 0x3e20000000000000L, 0x3f90000000000000L,
		0x2d00000000000000L, 0x2cb0000000000000L, 0x2e60000000000000L,
		0x2fd0000000000000L, 0x2bc0000000000000L, 0x2a70000000000000L,
		0x28a0000000000000L, 0x2910000000000000L, 0x2080000000000000L,
		0x2130000000000000L, 0x23e0000000000000L, 0x2250000000000000L,
		0x2640000000000000L, 0x27f0000000000000L, 0x2520000000000000L,
		0x2490000000000000L, 0x6c00000000000000L, 0x6db0000000000000L,
		0x6f60000000000000L, 0x6ed0000000000000L, 0x6ac0000000000000L,
		0x6b70000000000000L, 0x69a0000000000000L, 0x6810000000000000L,
		0x6180000000000000L, 0x6030000000000000L, 0x62e0000000000000L,
		0x6350000000000000L, 0x6740000000000000L, 0x66f0000000000000L,
		0x6420000000000000L, 0x6590000000000000L, 0x7700000000000000L,
		0x76b0000000000000L, 0x7460000000000000L, 0x75d0000000000000L,
		0x71c0000000000000L, 0x7070000000000000L, 0x72a0000000000000L,
		0x7310000000000000L, 0x7a80000000000000L, 0x7b30000000000000L,
		0x79e0000000000000L, 0x7850000000000000L, 0x7c40000000000000L,
		0x7df0000000000000L, 0x7f20000000000000L, 0x7e90000000000000L,
		0x5a00000000000000L, 0x5bb0000000000000L, 0x5960000000000000L,
		0x58d0000000000000L, 0x5cc0000000000000L, 0x5d70000000000000L,
		0x5fa0000000000000L, 0x5e10000000000000L, 0x5780000000000000L,
		0x5630000000000000L, 0x54e0000000000000L, 0x5550000000000000L,
		0x5140000000000000L, 0x50f0000000000000L, 0x5220000000000000L,
		0x5390000000000000L, 0x4100000000000000L, 0x40b0000000000000L,
		0x4260000000000000L, 0x43d0000000000000L, 0x47c0000000000000L,
		0x4670000000000000L, 0x44a0000000000000L, 0x4510000000000000L,
		0x4c80000000000000L, 0x4d30000000000000L, 0x4fe0000000000000L,
		0x4e50000000000000L, 0x4a40000000000000L, 0x4bf0000000000000L,
		0x4920000000000000L, 0x4890000000000000L, 0xd800000000000000L,
		0xd9b0000000000000L, 0xdb60000000000000L, 0xdad0000000000000L,
		0xdec0000000000000L, 0xdf70000000000000L, 0xdda0000000000000L,
		0xdc10000000000000L, 0xd580000000000000L, 0xd430000000000000L,
		0xd6e0000000000000L, 0xd750000000000000L, 0xd340000000000000L,
		0xd2f0000000000000L, 0xd020000000000000L, 0xd190000000000000L,
		0xc300000000000000L, 0xc2b0000000000000L, 0xc060000000000000L,
		0xc1d0000000000000L, 0xc5c0000000000000L, 0xc470000000000000L,
		0xc6a0000000000000L, 0xc710000000000000L, 0xce80000000000000L,
		0xcf30000000000000L, 0xcde0000000000000L, 0xcc50000000000000L,
		0xc840000000000000L, 0xc9f0000000000000L, 0xcb20000000000000L,
		0xca90000000000000L, 0xee00000000000000L, 0xefb0000000000000L,
		0xed60000000000000L, 0xecd0000000000000L, 0xe8c0000000000000L,
		0xe970000000000000L, 0xeba0000000000000L, 0xea10000000000000L,
		0xe380000000000000L, 0xe230000000000000L, 0xe0e0000000000000L,
		0xe150000000000000L, 0xe540000000000000L, 0xe4f0000000000000L,
		0xe620000000000000L, 0xe790000000000000L, 0xf500000000000000L,
		0xf4b0000000000000L, 0xf660000000000000L, 0xf7d0000000000000L,
		0xf3c0000000000000L, 0xf270000000000000L, 0xf0a0000000000000L,
		0xf110000000000000L, 0xf880000000000000L, 0xf930000000000000L,
		0xfbe0000000000000L, 0xfa50000000000000L, 0xfe40000000000000L,
		0xfff0000000000000L, 0xfd20000000000000L, 0xfc90000000000000L,
		0xb400000000000000L, 0xb5b0000000000000L, 0xb760000000000000L,
		0xb6d0000000000000L, 0xb2c0000000000000L, 0xb370000000000000L,
		0xb1a0000000000000L, 0xb010000000000000L, 0xb980000000000000L,
		0xb830000000000000L, 0xbae0000000000000L, 0xbb50000000000000L,
		0xbf40000000000000L, 0xbef0000000000000L, 0xbc20000000000000L,
		0xbd90000000000000L, 0xaf00000000000000L, 0xaeb0000000000000L,
		0xac60000000000000L, 0xadd0000000000000L, 0xa9c0000000000000L,
		0xa870000000000000L, 0xaaa0000000000000L, 0xab10000000000000L,
		0xa280000000000000L, 0xa330000000000000L, 0xa1e0000000000000L,
		0xa050000000000000L, 0xa440000000000000L, 0xa5f0000000000000L,
		0xa720000000000000L, 0xa690000000000000L, 0x8200000000000000L,
		0x83b0000000000000L, 0x8160000000000000L, 0x80d0000000000000L,
		0x84c0000000000000L, 0x8570000000000000L, 0x87a0000000000000L,
		0x8610000000000000L, 0x8f80000000000000L, 0x8e30000000000000L,
		0x8ce0000000000000L, 0x8d50000000000000L, 0x8940000000000000L,
		0x88f0000000000000L, 0x8a20000000000000L, 0x8b90000000000000L,
		0x9900000000000000L, 0x98b0000000000000L, 0x9a60000000000000L,
		0x9bd0000000000000L, 0x9fc0000000000000L, 0x9e70000000000000L,
		0x9ca0000000000000L, 0x9d10000000000000L, 0x9480000000000000L,
		0x9530000000000000L, 0x97e0000000000000L, 0x9650000000000000L,
		0x9240000000000000L, 0x93f0000000000000L, 0x9120000000000000L,
		0x9090000000000000L
	};

	private UInt64 seed;
	private UInt64 hash;

	public Crc64()
	{
		seed = DefaultSeed;
		Initialize();
	}

	public Crc64(UInt64 seed)
	{
		this.seed = seed;
		Initialize();
	}

	public override void Initialize()
	{
		hash = seed;
	}

	protected override void HashCore(byte[] buffer, int start, int length)
	{
		hash = CalculateHash(hash, buffer, start, length);
	}

	protected override byte[] HashFinal()
	{
		byte[] hashBuffer = UInt64ToBigEndianBytes(hash);
		this.HashValue = hashBuffer;
		return hashBuffer;
	}

	public override int HashSize
	{
		get { return 64; }
	}

	public static UInt64 Compute(UInt64 seed, byte[] buffer)
	{
		return CalculateHash(seed, buffer, 0, buffer.Length);
	}

	private static UInt64 CalculateHash(UInt64 seed, byte[] buffer, int start, int size)
	{
		UInt64 crc = seed;

		for (int i = start; i < size; i++)
			unchecked {
				crc = (crc >> 8) ^ table[(buffer[i] ^ crc) & 0xff];
			}

		return crc;
	}

	private byte[] UInt64ToBigEndianBytes(UInt64 x)
	{
		return new byte[] {
			(byte)((x >> 56) & 0xff),
			(byte)((x >> 48) & 0xff),
			(byte)((x >> 40) & 0xff),
			(byte)((x >> 32) & 0xff),
			(byte)((x >> 24) & 0xff),
			(byte)((x >> 16) & 0xff),
			(byte)((x >> 8) & 0xff),
			(byte)(x & 0xff) };
	}
}

To use this or the CRC-32 class to compute the hash for a file simply:

Crc64 crc64 = new Crc64();
String hash = String.Empty;

using (FileStream fs = File.Open("c:\\myfile.txt", FileMode.Open))
	foreach (byte b in crc64.ComputeHash(fs)) hash += b.ToString("x2").ToLower();

Console.WriteLine("CRC-64 is {0}", hash);

Whilst writing this I considered if I should implement some more advanced hashing algorithms missing from .NET like RIPEMD320 only to stumble across The Legion of Bouncy Castles C# Cryptography APIs which also includes generating PKCS #12 files and a whole bunch of encryption algorithms (but nothing as weak as CRC-64 ;-)

[)amien

08
Nov

Dissecting a C# Application - Inside SharpDevelop

Cover of Dissecting a C# ApplicationThis great book shows you the process, thinking and code behind the open-source .NET IDE SharpDevelop that went on to branch into MonoDevelop.

It was not in print for very long but Apress bought Wrox when they closed down and made the book freely available on its site for download in PDF format.

Alas, with their most recent web redesign their free e-books section has disappeared so I am temporarily hosting it here after recommending it to somebody interested in writing their own syntax highlighting editor on the MSDN forums.

Download Dissecting a C# Application - Inside SharpDevelop (Adobe PDF) (3.9MB)

[)amien

20
Oct

Extension Methods illustrated

Extension methods are a great new feature in the .NET Framework 3.5 that let you write new methods that appear to be part of existing classes without the need to subclass or modify them.

We can explain this in simple terms with an example. Here is a useful routine that takes a string and returns what it finds between two other strings that works just fine with .NET 2.0 and .NET 1.1.

public static string Between(string value, string start, string end)
{
    int startIndex = value.IndexOf(start, StringComparison.CurrentCultureIgnoreCase);
    if (startIndex == -1)
        return "";    startIndex += start.Length;

    int endIndex = value.IndexOf(end, startIndex, StringComparison.CurrentCultureIgnoreCase);
    if (endIndex == -1)
        return "";

    return value.Substring(startIndex, endIndex-startIndex);
}

If this method belonged to a static StringUtilities class then you could use it like this:

string newString = StringUtilities.Between(inputString, startingString, endingString);

The problem is knowing that the StringUtilities class within the project you are working on and until you know that IntelliSense can't even kick in. What would be nice is to add this to the String class but of course we can't because String is sealed and besides methods everywhere create String classes and not instances of your subclass.

What would be really cool is if Visual Studio and .NET could just realise that this method is static and takes a string parameter as it's first parameter and let it just appear as another method on the String class and just call StringUtilities behind the scenes.

That is exactly what the Extension Methods in .NET 3.5 achieve.

All we need to do is put this in front of the first parameter which will let VS and the compiler know that this method should appear as if it is a method against the type of that first parameter. The method must be static and visible to the code and curiously the class itself must also be static. Our signature now appears as:

public static string Between(string this value, string start, string end)

To call the method we simply press . after our string and IntelliSense displays all the usual methods and properties of the String class and any extension methods it can find in your project too which now includes our Between method giving us:

string newString = inputString.Between(startingString, endingString);

Nice but bear in mind the extension method can only access the public parts of the class it will appear with - there is no privileged access to protected properties or methods that would be available with subclassing!

[)amien

06
Aug

Multiple-inheritance, composition and single responsibility principle in .NET

.NET is often chided by C++ developers for failing to support multiple-inheritance. The reply is often Favor object composition over class inheritance - a mantra chanted from everywhere including the opening chapters of the Gang of Four's Design Patterns book.

If the accepted mantra is that your object should expose interfaces and delegate the implementation of those interfaces elsewhere then it could really do with some better support than .NET currently offers especially where the interface comprises more than a member or two.

Consider the following fragment of a class for customer price-lists (properties and methods omitted). We decide to support IList<ProductPrice> so that consumers of our class can add, remove and iterate over the prices in a familiar manner (principle of least surprise).

public class CustomerPriceList : IList<ProductPrice>
{ 
    private List<ProductPrice> productPrices = new List<ProductPrice>();
    public Customer Customer;
}

Implement interface

Visual Studio offers some assistance where you can choose Implement interface IList<ProductPrice> which gives you all the method definitions with the very unhelpful body of throwing an exception of "This method or operation is not implemented". It requires some work to fill in all these definitions to something that works:

public class CustomerPriceList : IList<ProductPrice>
{
    private List<ProductPrice> productPrices = new List<ProductPrice>();
    public Customer Customer;

    #region IList<ProductPrice> Members

    public int IndexOf(ProductPrice item) {
        return productPrices.IndexOf(item);
    }

    public void Insert(int index, ProductPrice item) {
        productPrices.Insert(index, item);
    }

    public void RemoveAt(int index) {
        productPrices.RemoveAt(index);
    }

    public ProductPrice this[int index] {
        get { return productPrices[index]; }
        set { productPrices[index] = value; }
    }

    #endregion

    #region ICollection<ProductPrice> Members

    public void Add(ProductPrice item) {
        productPrices.Add(item);
    }

    public void Clear() {
        productPrices.Clear();
    }

    public bool Contains(ProductPrice item) {
        return productPrices.Contains(item);
    }

    public void CopyTo(ProductPrice[] array, int arrayIndex) {
        productPrices.CopyTo(array, arrayIndex);
    }

    public int Count {
        get { return productPrices.Count; }
    }

    public bool IsReadOnly {
        get { return ((IList)productPrices).IsReadOnly; }
    }

    public bool Remove(ProductPrice item) {
        return productPrices.Remove(item);
    }

    #endregion

    #region IEnumerable<ProductPrice> Members

    public IEnumerator<ProductPrice> GetEnumerator() {
        return productPrices.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator() {
        return ((IEnumerable) productPrices).GetEnumerator();
    }

    #endregion
}

This is a lot of effort for a cluttered solution.

Use inheritance to subclass List<T>

public class CustomerPriceList : List<ProductPrice>
{
    public Customer Customer;
}

Small amount of code but not an option if you have a class hierarchy in place or need to implement multiple interfaces.

Expose IList<ProductPrice> property directly

public class CustomerPriceList : IListable<ProductPrice>
{
    private List<ProductPrice> productPrices = new List<ProductPrice>();
    public Customer Customer;
    public IList<ProductPrice> ProductPrices {
        get { return productPrices; }
    }
}

This works but means CustomerPriceList can not control any of the IList implementation such as validation.

Methods may also start accepting IList<ProductPrice> instead of CustomerPriceList because developers imagine the parts to be more decoupled than they actually are and are encouraged to code to interfaces not concrete classes.

Refactoring away from this at a later date would require a IList<ProductPrice> wrapper than delegated calls back to the containing class to prevent an interface-breaking change.

Introduce interface to declare IList<ProductPrice> available

Add an interface that signifies a IList<ProductPrice> can be obtained by calling the named method, e.g.

public interface IListable<T>
{
    IList<T> GetList();
}

This is a similar pattern to that of IEnumerable<T> and IEnumerator<T> whereby one interface signifies the availability of the other. In this example our class would look like:

public class CustomerPriceList : IListable<ProductPrice>
{
    private List<ProductPrice> productPrices = new List<ProductPrice>();
    public Customer Customer;
    public IList<ProductPrice> GetList() {
        return productPrices;
    }
}

Which is less code, a closer adherence to single responsibility principle (SRP) and the ability to change without breaking the interface although it still does nothing to prevent passing IList or IListable interfaces where CustomerPriceList would be more suitable. An IPriceList class could be introduced although it starts to feel like abstract infinity.

Improved support from .NET

I'd really like to see .NET improve on the support for interfaces and composition, like perhaps the following:

public class CustomerPriceList : IList<ProductPrice> goto productPrice
{
    private IList<ProductPrice> productPrice = new IList<ProductPrice>();
    public Customer Customer;
}

This would signify to the compiler that all IList<T> interfaces should be wired up to the productPrice variable unless explicitly defined and gives goto a whole new lease of life ;-)

[)amien

20
Oct

.NET quick samples: Uptimes, ages, rounding to n places

Just a few quick .NET samples for performing some common tasks that the .NET Framework doesn't do for you:

System uptime

using System.Diagnostics;

public TimeSpan GetUptime() {
    PerformanceCounter systemUpTime = new PerformanceCounter("System", "System Up Time");
    systemUpTime.NextValue(); // Required to work!
    return TimeSpan.FromSeconds(systemUpTime.NextValue())));
}

Calculating age

public int GetAge(DateTime birthday) { 
    int years = DateTime.Now.Year - birthday.Year;
    return (birthday.DayOfYear >= DateTime.Now.DayOfYear) ? years : years - 1;
}

Rounding to n decimal places

public decimal ArithmeticRound(decimal d, int decimals) {
    decimal power = (decimal)Math.Pow(10, decimals);
    return (decimal.Floor((Math.Abs(d) * power) + 0.4m) / power) * Math.Sign(d);
}

[)amien

08
Sep

Subtleties of .NET: int i; and int i=0 are not the same

Every value type in .NET defaults to a sensible value so you might be thinking that int i and int i = 0 are logically the same.

This is often true however consider the case of a variable declared in-line inside a loop and things are a little different (using Decimal in this example)

foreach(Customer customer in customers) {
    decimal customerSalesYTD = 0;
    foreach(Invoice invoice in customer.Invoices.ForYear(DateTime.Now.Year)
        customerSalesYTD += invoice.Value;
    SalesTotal.Set(customer, customerSalesYTD);
}

Here the 0 makes all the difference because although you have created the variable inside the loop by the time the runtime gets to this the optimizer has moved the object creation to outside the loop.

[)amien




Feed subscription

Subjects