I\'m writing a C# programlet to crawl a directory and give me a listing of files whose date in the last CSV line is less than the current date. Since this is a programlet, I\'m
No, C# (like C++ before it) does not allow an overload where the only difference is in the return type.
The big problem here is which one do you call if you don't assign the return value? Which one do you call if both types are castable to the return value assignment? Its highly ambiguous, and so not allowed.
You can't have two methods differing just for the return type, since the code can't infer which should be the return type.
Correct, C#
does not let you overload methods on return types only.
Consider what happens if I just call dateStringGetter()
without assignment of return value.
Which method have I called?
So I suppose C# does not overload return types?
No, indeed it doesn't. The return type isn't part of the signature.
From section 3.6 of the C# 5 specification (emphasis mine):
The signature of a method consists of the name of the method, the number of type parameters and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. The signature of a method specifically does not include the return type, the
params
modifier that may be specified for the right-most parameter, nor the optional type parameter constraints.
and
Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.
And additionally (for completeness):
Although
out
andref
parameter modifiers are considered part of a signature, members declared in a single type cannot differ in signature solely byref
andout
.
Aside from anything else, this restriction helps with readability - it can be hard enough to tell which overload is being called sometimes even when they vary by parameters - it would be even worse if methods could be overloaded by return type. In this case it doesn't even make sense for the methods to be overloaded, as they do opposite things. You should only overload a method if all the overloads perform the same basic task.
As a side note, your methods don't currently follow .NET naming conventions - and you should be using standard formatting/parsing methods instead of rolling your own.
Based on "programlet to crawl a directory and give me a listing of files whose date in the last CSV line is less than the current date. Since this is a programlet, I'm not really spending too much time making the code very clean or anything" I propose something similar to the following which I've used in the past. Take it or leave it.
What it does: Specify a root directory, function gets all files within directory of given type (for your time requirement, modify files.add(...) to match your criteria)
Only leaving this here as an alternative to your work since you said you don't want to spend much time on it.
var data = GetAllFilesOfType('c:\rootpath', 'csv')
/// <summary>
/// Gets files of specified type and appends them to the file list.
/// </summary>
/// <param name="basepath">Starting file path</param>
/// <param name="type">File type - Do not include prefix ('txt' instead of '*.txt</param>
/// <returns>Returns results of WalkDirectoryTree</returns>
public static IEnumerable<FileInfo[]> GetAllFilesOfType(string basepath, string type)
{
var root = new DirectoryInfo(basepath);
return WalkDirectoryTree(root, type);
}
/// <summary>
/// Recursively gets all files from a specified basepath (provided by GetAllFilesOfType)
/// and appends them to a file list. This method reports all errors, and will break on
/// things like security errors, non existant items, etc.
/// </summary>
/// <param name="root">Initially specified by calling function, set by recursive walk</param>
/// <param name="type">File type that is desired. Do not include prefix ('txt' instead of '*.txt')</param>
/// <returns></returns>
private static List<FileInfo[]> WalkDirectoryTree(DirectoryInfo root, string type)
{
var files = new List<FileInfo[]>();
//Traverse entire directory tree recursively - Will break on exception
var subDirs = root.GetDirectories();
foreach (var data in subDirs.Select(dirInfo => WalkDirectoryTree(dirInfo, type)).Where(data => data.Count > 0))
{
files.AddRange(data);
}
//If any file is found, add it to the file list
if (root.GetFiles(string.Format("*.{0}", type)).Length > 0)
{
files.Add(root.GetFiles(string.Format("*.{0}", type)));
}
//Kicks the file list up a level until it reaches root, then returns to calling function
return files;
}
There is always a way to hammer it into place, unfortunately:
class Program
{
static void Main(string[] args)
{
object stringDate = "";
object dateTime = new DateTime();
DateUtils.DateStringGetter(ref stringDate);
DateUtils.DateStringGetter(ref dateTime);
}
}
public static class DateUtils
{
private static DateTime DateStringConverter(string mmddyyyy, char delim = '/')
{
string[] date = mmddyyyy.Split(delim);
DateTime fileTime = new DateTime(Convert.ToInt32(date[2]), Convert.ToInt32(date[0]),
Convert.ToInt32(date[1]));
return fileTime;
}
public static void DateStringGetter(ref object date)
{
string sYear = DateTime.Now.Year.ToString();
string sMonth = DateTime.Now.Month.ToString().PadLeft(2, '0');
string sDay = DateTime.Now.Day.ToString().PadLeft(2, '0');
if (date is String)
{
date = sMonth + '/' + sDay + '/' + sYear;
}
if (date is DateTime)
{
date = DateStringConverter(sMonth + '/' + sDay + '/' + sYear);
}
}
}