C#: Calling a Constructor from Another Constructor in the Same Class


If you have a child class that extends or inherits from another class, you can ensure a specific constructor in the parent class is called by using the : base() syntax as shown below.

public class Parent
{
    public Parent()
    {
        // Empty constructor called by default        
    }

    public Parent(int value)
    {
        this.Value = value;       
    }
}

public class Child : Parent
{
    public Child(int value) : base(value)
    {
        // Using the base keyword and supplying the value
        // parameter, ensures that the second constructor
        // in the Parent class is called rather than
        // the first
    }
}

In the example above, when creating a new Child object, the second constructor in the Parent class will be called instead of the first. But, what if you want to call one constructor from another in the same class? Take the example below, where each constructor assigns a value to the DistanceTraveled variable.

public class Trip
{    
    public Trip(decimal distanceTraveled)
    {
        this.DistanceTraveled = distanceTraveled;   
    }

    public Trip(decimal travelTime, decimal velocity)
    {
        this.DistanceTraveled = travelTime * velocity;
    }
}

While this code works, you are updating the DistanceTraveled variable in two different places which is less than desirable from a maintenance perspective (understandably this is a trivial example but with little thought I'm sure you can think of a real world situation where this would this could cause a larger problem). It would be nice to be able to call the first constructor from the second, passing in the product of the two parameters. Using the base keyword won't work in this situation as we want to call a constructor in the same class, not a parent class. It turns out that if we simply swap 'base' for 'this', our goal can be achieved.

public class Trip
{    
    public Trip(decimal distanceTraveled)
    {
        this.DistanceTraveled = distanceTraveled;
    }

    public Trip(decimal travelTime, decimal velocity) : this (travelTime * velocity)
    {
        // the DistanceTraveled variable is updated by a call to the first constructor
    }
}

C#: Compare Application Version Numbers


UPDATE: As discussed in the comments, 99% of the time using the System.Version class included in the .net Framework will suffice for comparing application version numbers. Documentation for this can be found here. The below post will help you if for some reason (ex. you use commas instead of periods to separate the version number) the System.Version class will not work

When incorporating an automatic update feature into an application, one of the things that you will need to do is compare the installed version number to the currently available version number. Given version numbers of the format ‘X.X.X.X’ I have seen some people suggest simply removing the periods, converting the string to an integer and doing a simple comparison of the integers. Such a solution works great if you have complete control over the format of the version number and you can ensure the number of digits per grouping stays the same. But, suppose you have the following two version numbers: 1.4.0 and 1.1.28. Following the logic explained above, you will be comparing the integers 140 and 1128 and the second version will be determined to be greater than the first, which is incorrect.

In order to alleviate this problem, I have created the following method below to correctly compare two version numbers. This method uses the SplitToList extension which takes a string, splits it based on a given string and then converts each element to the specified type. You can find a more detailed explanation and the code here.

public static int CompareVersionNumbers(string versionA, string versionB)
{           
    // Convert each version numbers string to a list of integers
    List<int> a = versionA.SplitToList<int>(".");
    List<int> b = versionB.SplitToList<int>(".");            
   
    // Ensure that each of the lists are the same length
    while(a.Count < b.Count) { a.Add(0); }
    while(b.Count < a.Count) { b.Add(0); }

    // Compare elements of each list
    for (int i = 0; i < a.Count; i++)
    {
        // If the element from list A is greater than B, 
        // versionA is greater than versionB and visa versa.
        // If they are equal, go to the next element.
        if (a[i] > b[i])
            return 1;
        else if (b[i] > a[i])
            return -1;
    }

    // If we reach this point, the versions are equal
    return 0;
}

Crystal Reports: Displaying a Check Mark for a Boolean Value


Crystal Reports gives you a few options of how to display a boolean value including Yes and No, Y and N, True and False, and 0 and 1. But, frequently I want to show a check mark for true values and the empty string for false values. This isn’t a difficult task, I just never remember the correct character codes.

To do this, either create a new formula field or enter the following formula in the Display String formula of the field and set the font property to Windings.

if {Table.Field} then
    Chr(252)
else
    ""

The above is illustrated in the Void column in the image below. When the check has been voided, a check mark appears in the Void column.

If you want to display a check box with a check mark for true and empty for false, use the following code.

if {Table.Field} then 
    Chr(254) 
else
    Chr(168)

C#: DataGridViewComboBoxColumn Displaying Different Values in Drop Down List


You can add a DataGridViewComboBoxColumn to the DataGridView to allow your users the ability to select from a list of items when editing the cell’s contents. I ran into a situation today where I needed to display a description of each item in the drop down list of the ComboBox but after the user selected an item, I only wanted the name of the item to be displayed and not the description as well. The following image shows an example of what I wanted; the drop down list shows a description of each animal but when selected, only the type of the animal is shown.

Unfortunately, the DataGridViewComboBoxColumn has a single DisplayMember property that lets you specify which property of the objects bound to the control is displayed to the user. So, to allow for the desired result, I needed to change the DisplayMember property when the drop down list is visible to show both the type and description and when the drop down list is not visible, to only show the type. The code below allows us to accomplish just this.

The form is setup with a DataGridView and two columns, if which the first is a ComboBoxColumn. I have a simple Animal class as defined below.

public class Animal
{
    public string Type { get; set; }
    public string Description { get; set; }

    public string TypeAndDescription { get { return Type + " - " + Description; } }
}

At the initialization if the form, we simply add a few Animal objects to the column's Items collection and set the default DisplayMember to Type.

public Form1()
{
    InitializeComponent();

    this.clmAnimal.Items.Add(new Animal() { Type = "Dog", Description = "Fury animal that barks" });
    this.clmAnimal.Items.Add(new Animal() { Type = "Cat", Description = "Fury animal that meows" });
    this.clmAnimal.Items.Add(new Animal() { Type = "Mouse", Description = "Small rodent with a tail" });
    this.clmAnimal.Items.Add(new Animal() { Type = "Rabbit", Description = "Small with two large ears" });            

    this.clmAnimal.DisplayMember = "Type";
    this.clmAnimal.DropDownWidth = 180;
}

From the designer, there is no way to wire up the DataGridViewComboBoxColumn DropDown and DropDownClosed events. To do this, we need to handle the EditingControlShowing event of the DataGridView. This event fires when a control used for editing the value in the DataGridView is shown. This event will be fired when the user clicks on the cell to select an item from the ComboBox. Add the following code to this event.

private void dataGridViewAnimals_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    // Cast the editing control to a ComboBox
    ComboBox cmbBx = e.Control as ComboBox;

    // If the cast was successful, wire up the DropDown and DropDownClosed events
    if (cmbBx != null)
    {
        cmbBx.DropDown -= new EventHandler(ComboBoxCell_DropDown);
        cmbBx.DropDown += new EventHandler(ComboBoxCell_DropDown);

        cmbBx.DropDownClosed -= new EventHandler(ComboBoxCell_DropDownClosed);
        cmbBx.DropDownClosed += new EventHandler(ComboBoxCell_DropDownClosed);
    }
}

Then add the following code to handle the DropDown and DropDownClosed events.

private void ComboBoxCell_DropDown(object sender, EventArgs e)
{
    // When the drop down list appears, change the DisplayMember property of the ComboBox
    // to 'TypeAndDescription' to show the description
    DataGridViewComboBoxEditingControl cmbBx = sender as DataGridViewComboBoxEditingControl;
    if (cmbBx != null)
        cmbBx.DisplayMember = "TypeAndDescription";
}

private void ComboBoxCell_DropDownClosed(object sender, EventArgs e)
{
    // When the drop down list is closed, change the DisplayMember property of the ComboBox
    // back to 'Type' to hide the description
    DataGridViewComboBoxEditingControl cmbBx = sender as DataGridViewComboBoxEditingControl;
    if (cmbBx != null)
        cmbBx.DisplayMember = "Type";
}

The above code will allows us to display a different value when the ComboBox's drop down list is displayed than what is displayed after the user selects an item from the list.

C#: String to Integer, Decimal, Float, or Any Type of Array or List


The string.Split method is a great tool that can be used when manipulating strings. But, this method simply returns an array of strings when frequently I need a collection returned in the type that the strings actually represent. To fix this you simply have to loop through each item in the string array and convert it to its representative type. For example, if you are reading in a comma delimited file of temperatures, you can split on the commas and then loop through the returned array, parsing each element and adding it to a new list, as follows:


string temperatures = "67.2,92.1,78.2,100.3,89.2";

string[] tempArray = temperatures.Split(',');

List<float> temps = new List<float>();
foreach (string temp in tempArray)
    temps.Add(float.Parse(temp));

While such a solution is common and quite acceptable, I wanted to make it simpler and reusable. To do such, I decided to implement the above logic in a generic extension method.


/// <summary>
/// Splits a string using the supplied separator and casts each element to the
/// indicated type.
/// </summary>
/// <typeparam name="T">The type of the List to return</typeparam>        
/// <param name="s">The string on which the operation will be performed.</param>
/// <param name="separator">An array of strings that delimit the substrings in this string, an empty
///     array that contains no delimiters, or null.</param>
/// <returns>A List of type T containing the elements formed after splitting the string using
/// the given separators.</returns>
public static List<T> SplitToList<T>(this string s, params string[] separator)
{
    return s.SplitToList<T>(StringSplitOptions.None, separator);
}

/// <summary>
/// Splits a string using the supplied separator and casts each element to the
/// indicated type.
/// </summary>
/// <typeparam name="T">The type of the List to return</typeparam>        
/// <param name="s">The string on which the operation will be performed.</param>
/// <param name="options">Specify System.StringSplitOptions.RemoveEmptyEntries to omit empty array
///     elements from the array returned, or System.StringSplitOptions.None to include
///     empty array elements in the array returned.</param>
/// <param name="separator">An array of strings that delimit the substrings in this string, an empty
///     array that contains no delimiters, or null.</param>
/// <returns>A List of type T containing the elements formed after splitting the string using
/// the given separators.</returns>
public static List<T> SplitToList<T>(this string s, StringSplitOptions options, params string[] separator)
{
    // Split the string based on the supplied separators
    string[] array = s.Split(separator, options);
    
    List<T> values = new List<T>();

    // Convert each element in the array to the indicated type
    foreach (string element in array)
        values.Add((T)Convert.ChangeType(element, typeof(T)));                

    return values;
}

Now our temperature example can be reduced to the following:


string temperatures = "67.2,92.1,78.2,100.3,89.2";
List<float> temps = temperatures.SplitToList<float>(",");

Below are some other examples of how this extension method could be used:

string s1 = "true-false-true-true-true-false";
List<bool> bools = s1.SplitToList<bool>("-");

string s2 = "a b c d e f g h i j";
List<char> chars = s2.SplitToList<char>(" ");

// Split on both commas and periods
string s3 = "1,3,4.5.7,1.4,6.7,8.2";
List<int> ints = s3.SplitToList<int>(",", ".");
Follow

Get every new post delivered to your Inbox.

Join 67 other followers