C#: Method with Arbitrary or Variable Number of Parameters


Normally when I create a method that needs to accept an arbitrary or variable number of parameters or arguments I just accept an array of values. This works great but it does require you to instantiate a new array and populate it every time you want to call the method. Not a big deal but as you can see below it makes the code a bit messy.

static void Main(string[] args)
{
    CountParameters(new int[] { });
    CountParameters(new int[] { 5, 3, 6 });
    CountParameters(new int[] { 1, 2, 3, 4 });
    CountParameters(new int[] { 8, 3, 78, 234, 2, 56, 87 });
}

public static void CountParameters(int[] numbers)
{
    Console.WriteLine(numbers.Length + " parameters passed in");
}

// Output
// ------
// 0 parameters passed in
// 3 parameters passed in
// 4 parameters passed in
// 7 parameters passed in

But, if you simply add the ‘params’ keyword before the parameter definition, this allows you to call the method by just specifying a comma delimited list of arguments.

static void Main(string[] args)
{
    CountParameters();
    CountParameters(5, 3, 6);
    CountParameters(1, 2, 3, 4);
    CountParameters(8, 3, 78, 234, 2, 56, 87);
}

public static void CountParameters(params int[] numbers)
{
    Console.WriteLine(numbers.Length + " parameters passed in");
}

// Output
// ------
// 0 parameters passed in
// 3 parameters passed in
// 4 parameters passed in
// 7 parameters passed in

You can also specify other parameters for the method but the parameter with the ‘params’ keyword must be the last parameter definition. Further you can only add the ‘params’ keyword to one parameter in the list of parameters. More information about the ‘params’ keyword can be found here.

Interestingly, if you look at the disassembly of the second code segment above, you will see the following:

private static void Main(string[] args)
{
    CountParameters(new int[0]);
    CountParameters(new int[] { 5, 3, 6 });
    CountParameters(new int[] { 1, 2, 3, 4 });
    CountParameters(new int[] { 8, 3, 0x4e, 0xea, 2, 0x38, 0x57 });
    Console.ReadLine();
}

public static void CountParameters(params int[] numbers)
{
    Console.WriteLine(numbers.Length + " parameters passed in");
}

It simply instantiates a new array of integers and passes it to the CountParameters method as we did in the first approach. So this is obviously just a way to make your code a bit more readable.

LINQ: Selecting Multiple Properties from a List of Objects


In a previous post I discussed how to use LINQ to flatten a list of lists. Yesterday and ran across a slightly different situation but that used the same solution.

I had a list of objects that each contained three separate integer values and I wanted to extract the three values from each object and put them all in a single list. So, all you need to do is create a new List that has each of the three values in each object as elements of the list and then use the SelectMany method to flatten the list of lists we just created.

private class Foo
{
    public int Item1;
    public int Item2;
    public int Item3;
}

static void Main(string[] args)
{
    List<Foo> foos = new List<Foo> 
                           { 
                               new Foo() { Item1 = 1, Item2 = 2, Item3 = 3 },
                               new Foo() { Item1 = 4, Item2 = 5, Item3 = 6 },
                               new Foo() { Item1 = 7, Item2 = 8, Item3 = 9 }
                           };

    // Create a list of lists where each list has three elements corresponding to 
    // the values stored in Item1, Item2, and Item3.  Then use SelectMany
    // to flatten the list of lists.
    var items = foos.Select(f => new List<int>() { f.Item1, f.Item2, f.Item3 }).SelectMany(item => item).Distinct();

    foreach (int item in items)
        Console.WriteLine(item.ToString());
    
    Console.ReadLine();
}

// Output
// ------
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
Posted in LINQ. Tags: , . 2 Comments »

C#: DateTime.ToString() Format – Apostrophe Before the Year


I was trying to use the DateTime.ToString(string) method to create a string that had the abbreviated month and last two digits of the year but I wanted to add an apostrophe before the year to produce something like Sep ’10 for September 2010. It took me a while to figure our the correct escaping sequence but here it is.

DateTime date = DateTime.Today;
Console.WriteLine(date.ToString("MMM \"'\"yy"));

// Output
// ------
// Sep '10

Any text between the two escaped quotation marks (\”…\”) will be printed as literal text.

C#: Creating and Sending UDP Packets


I needed to test an application today that accepts UDP packets so I searched the internet for a simple program to create and send UDP packets and found a bunch of complex programs that didn’t work (or at least that I couldn’t figure out within a couple of minutes!). So, after I wasted a bunch of time I just decided to write my own method to create and send the UDP packets myself. I would have saved a ton of time had I just done this from the beginning!

using System.Net;
using System.Net.Sockets;

...

/// <summary>
/// Sends a sepcified number of UDP packets to a host or IP Address.
/// </summary>
/// <param name="hostNameOrAddress">The host name or an IP Address to which the UDP packets will be sent.</param>
/// <param name="destinationPort">The destination port to which the UDP packets will be sent.</param>
/// <param name="data">The data to send in the UDP packet.</param>
/// <param name="count">The number of UDP packets to send.</param>
public static void SendUDPPacket(string hostNameOrAddress, int destinationPort, string data, int count)
{
    // Validate the destination port number
    if (destinationPort < 1 || destinationPort > 65535)
        throw new ArgumentOutOfRangeException("destinationPort", "Parameter destinationPort must be between 1 and 65,535.");

    // Resolve the host name to an IP Address
    IPAddress[] ipAddresses = Dns.GetHostAddresses(hostNameOrAddress);
    if (ipAddresses.Length == 0)
        throw new ArgumentException("Host name or address could not be resolved.", "hostNameOrAddress");

    // Use the first IP Address in the list
    IPAddress destination = ipAddresses[0];            
    IPEndPoint endPoint = new IPEndPoint(destination, destinationPort);
    byte[] buffer = Encoding.ASCII.GetBytes(data);

    // Send the packets
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);           
    for(int i = 0; i < count; i++)
        socket.SendTo(buffer, endPoint);
    socket.Close();            
}

Update: So, it turns out that the .NET Framework actually already has a class for sending UDP packets called UdpClient. The documentation for it can be found here. It definitely provides a lot more options but if you are looking for a simple method, the above works too!

C#: List.Contains Method – Case Insensitive


I had a list of strings and needed to check whether or not a specific string was contained within the list ignoring the character casing.  Pre-LINQ days you would have had to loop through the entries calling the .ToLower or ToUpper method on each of the elements or using the string.Compare method.  But thanks to LINQ, one simple method will take care of this for us:

List<string> list = new List<string>() { "a", "b", "c", "d", "e" };
string value = "A";

if (list.Contains(value, StringComparer.OrdinalIgnoreCase))
    Console.WriteLine(value + " is in the list!");
else
    Console.WriteLine(value + " is not in the list!");
Follow

Get every new post delivered to your Inbox.

Join 54 other followers