2014-06-23 91 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

相關問題