2014-06-23 62 views
3

我正在写一个C#程序来抓取一个目录,并给我一个列表,其中最后一个CSV行的日期小于当前日期的文件。由于这是一个程序小组,我并没有花费太多时间让代码变得非常干净或任何东西 - 但我想这只是一个意见问题。C#没有推断通过返回类型的重载方法

好奇的是以下一组代码片段。三个静态方法都在同一个类中。

public 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 string dateStringGetter() 
     { 
      string sYear = DateTime.Now.Year.ToString(); 
      string sMonth = DateTime.Now.Month.ToString().PadLeft(2, '0'); 
      string sDay = DateTime.Now.Day.ToString().PadLeft(2, '0'); 
      return sMonth + '/' + sDay + '/' + sYear; 
     } 

     public static DateTime dateStringGetter() 
     { 
      string datestring = dateStringGetter(); 
      return dateStringConverter(datestring); 
     } 

该错误消息表示:

Error 1 Type 'Poller.Program' already defines a member called 
'dateStringGetter' with the same parameter types  

的问题的方法是dateStringGetter(),的第二个重载拷贝当然具有相同的参数类型为第二个版本(无),但有两个完全不同的返回类型。一个是DateTime,另一个是字符串。带有DateTime返回类型的版本(一串错误编码)使用字符串类型调用dateStringGetter()的版本。

这不是好奇吗?那C#不会重载基于返回类型的方法吗?我想我已经完成了库的重载,它会根据通话自动检测我想要的返回类型 - 但我不确定。有些事情对此感觉不对。

所以我想C#不重载返回类型?

+2

简单 - 你_can't_有两种方法相差仅返回类型。使用不同的名字。 –

回答

8

所以我想C#不重载返回类型?

不,事实上并非如此。返回类型不是签名的一部分。

从C#5规范的第3.6节(重点煤矿):

的方法的签名由该方法的名字,类型参数的数目和类型和种类(值,参考,或输出)的每个形式参数,按照从左到右的顺序来考虑。为了这些目的,在形式参数的类型中发生的方法的任何类型参数不是通过其名称来标识的,而是通过其在方法的类型参数列表中的序号位置来标识的。 方法的签名特别不包括返回类型,可能为最右边参数指定的params修饰符,也不包括可选类型参数约束。方法

重载允许类,结构或接口声明具有相同名称的多个方法,条件是它们的签名在该类,结构或接口中是唯一的。

并且附加(出于完整性):

虽然outref参数改性剂被认为是签名的一部分,成员在一个单一的类型中声明可以在签名仅由refout没有不同。

从别的

除此之外,这种限制有助于可读性 - 它可以是够难判断哪些超载被有时也被称为甚至当他们通过参数变化 - 这将是更加糟糕,如果方法可以通过返回类型超载。在这种情况下,这些方法甚至没有意义,因为它们的做法与相反。如果所有重载执行相同的基本任务,则只应该重载一个方法。请注意,您的方法目前不遵循.NET命名约定 - 您应该使用标准的格式化/解析方法,而不是滚动自己的方法。

+1

我不知道最后一部分(尽管它很有意义)。伟大的信息! – BradleyDotNET

+0

认真 - 57秒直到答案?!当然,FGITW,乔恩。非常感谢!我将对.NET命名约定做一些研究,并对我的(非马虎)编码风格进行一些更改。 – alvonellos

0

对于返回类型,您不能有两种不同的方法,因为代码无法推断哪个应该是返回类型。

2

不,C#(与之前的C++一样)不允许超载,其中唯一的区别在于返回类型

这里的一个大问题是,如果你不分配返回值,你打电话给哪一个?如果两种类型都可以转换为返回值赋值,您打算哪一个?它高度模糊,因此不被允许。

0

正确,C#不允许您仅在返回类型上重载方法。

请考虑如果我只是拨打dateStringGetter()而不指定返回值会发生什么。

我打了哪个方法?

1

基于“抓取目录的程序组,并给我一个列表,其中最后一个CSV行的日期小于当前日期的文件列表。由于这是一个程序集,因此我并没有真正花费太多时间来制作代码非常干净或任何东西“我提出了类似于以前使用的以下内容。要么接受,要么离开它。

它所做的:指定一个根目录,函数获取给定类型的目录中的所有文件(您的时间要求,修改files.add(...),以符合您的标准)

仅在离开这个在这里作为你的工作的替代品,因为你说你不想花太多时间在它上面。

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; 
    } 
+0

这是一个很好的答案!感谢代码! – alvonellos

1

总是有办法将其锤到位,遗憾的是:

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); 
     } 

    } 
} 
+0

这是一个好主意!谢谢你的伟大答案。 – alvonellos

相关问题