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#: 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>(",", ".");

C#: FTP Upload Error – The remote server returned an error: (550) File unavailable (e.g., file not found, no access).


I developed an application a while back that automatically backs up a group of SQL servers every night and then uploads the backups to an offsite location using FTP. The application has worked flawlessly for months now so I was quite surprised to get a call this morning saying that the automatic backups failed last night. I checked the error logs and saw a 550 error – “The remote server returned an error: (550) File unavailable (e.g., file not found, no access).” I then ran the program through a debugger again saw that this exception was thrown while attempting to close the FileStream.

I tested for the usuals, spaces in the ftp uri, ensuring correct permissions for ftp user, changed the code around to see if it was a coding issue, and a bunch of other things and nothing seemed to fix the problem. I could login to the server with the same credentials using Windows Explorer and FileZilla and I could upload a test text file. I had no idea what was going on. So, after a long time, too long, I whipped out good ol’ WireShark to see if I could discern anything from the actual packet transfer (something I should have done first!) and lo and behold, there I found the error in plain text.

“There is not enough space on the disk.” Such a problem did not cross my mind as the hosting plan we pay for comes with unlimited disk space! Further, the test file I uploaded was a couple of KB rather than the 4 or 5 MB backups that were trying to be uploaded so I wasn’t seeing the error. Turns out despite what it says in the contract, there are still physical limits on the server. Ridiculous! :) After a short call to the hosting company the problem was resolved.

Despite the fact that the server was giving the real reason for the error, the .NET Framework did not relay the message. Kind of strange if you ask me but such is life. Nonetheless, a valuable lesson was learned: when debugging FTP issues, always pull out WireShark!

Posted in .NET Framework. Tags: , , . 4 Comments »

C#: String Concatenation using StringBuilder and LINQ Aggregate Function


I always forget how to do this so I thought I would post it mainly for my reference.

List<string> nameList = new List<string>() { "Roger", "Clark", "Wonda", "Anita" };

// A useless Select call in this instance just to remind you
// that you coulde use LINQ to select a set of strings
// from a list of objects
StringBuilder names = nameList.Select(n => n)
                              .Aggregate(new StringBuilder(), (current, next) => current.Append(next).Append(", "));

// Remove the trailing comma and space
if (names.Length > 1)
    names.Remove(names.Length - 2, 2);

Console.WriteLine(names.ToString());

// Output
// ------
// Roger, Clark, Wonda, Anita

C#: Yield Statement Used to Reduce Accessor Code


Often in Windows Forms development I run into the situation where I need to show a list of items to a user from which they can select multiple items. Usually I will accomplish this using a dialog form with a CheckedListBox. The user simply checks the box next to each item they want to select and then clicks OK. For example, here is one that allows a user to override various form letter merge fields.

Before today, I would include an accessor method in the form class similar to the following:

public List<string> SelectedFields
{
    get
    {
        List<string> selectedFields = new List<string>();

        foreach (var item in this.listBxMergeFields.CheckedItems)
            selectedFields.Add(item.ToString());

        return selectedFields;
    }
}

I always thought it was a pain to have to instantiate a new List object and populate it when I wasn’t performing any operations on the List other than adding items. Enter the yield statement. It turns out that the following code can be used to solve my little annoyance.

public IEnumerable<string> SelectedFields
{
    get
    {
        foreach (var item in this.listBxMergeFields.CheckedItems)
            yield return item.ToString();
    }
}

When used in this fasion, the yield statement will return the accumulated values that result from the expression to its right. Pretty handy way to tidy up the code if you ask me! For more information and uses, check the MSDN documentation here.

(I admit this is a relatively trivial way of using this as we are just enumerating over one collection to create another, but the concept can be applied to other situations.)

Follow

Get every new post delivered to your Inbox.

Join 66 other followers