c#不通过返回类型推断重载方法

本文关键字:重载 方法 返回类型 | 更新日期: 2023-09-27 18:09:54

我正在编写一个c#程序来抓取目录并给我一个文件列表,其最后一行CSV中的日期小于当前日期。因为这是一个程序集,所以我并没有花太多的时间来使代码变得非常干净——但我想这只是个人意见的问题。

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

   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,另一个是string。具有DateTime返回类型的版本——在一个错误编码的字符串中——调用具有字符串类型的dateStringGetter()的版本。

这不是很奇怪吗?c#不会仅仅基于返回类型重载方法?我认为我已经完成了库的重载,这些库将根据调用自动检测我想要的返回类型——但我不确定。这事总让人觉得不对劲。

所以我想c#没有重载返回类型?

c#不通过返回类型推断重载方法

所以我想c#没有重载返回类型?

不,确实没有。返回类型不是签名的一部分。

来自c# 5规范第3.6节(重点是我的):

方法的签名由方法的名称、类型参数的数量以及每个形式参数的类型和种类(值、引用或输出)组成,按照从左到右的顺序考虑。出于这些目的,在形式形参的类型中出现的方法的任何类型参数不是通过其名称来标识的,而是通过其在方法的类型参数列表中的顺序位置来标识的。方法的签名不包括返回类型,可以为最右边的参数指定的params修饰符,也不包括可选的类型参数约束。

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

另外(为了完整):

虽然outref参数修饰符被认为是签名的一部分,但在单个类型中声明的成员不能仅仅由refout在签名中不同。

除此之外,这个限制有助于提高可读性——有时很难判断调用的是哪个重载,即使它们随参数而变化——如果方法可以按返回类型重载,情况会更糟。在这种情况下,重载方法甚至没有意义,因为它们做相反的事情。只有当所有的重载都执行相同的基本任务时,你才应该重载一个方法。

作为一个边注,你的方法目前不遵循。net命名约定-你应该使用标准的格式化/解析方法,而不是自己的。

不,c#(像之前的c++一样)不允许重载,其中唯一的区别是返回类型

这里的大问题是,如果你不分配返回值,你调用哪一个?如果两种类型都可赋值到返回值赋值,您调用哪一种?

基于"programlet抓取目录,并给我一个文件列表,其最后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;
    }

总有一种方法可以把它敲到位,不幸的是:

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

不能仅仅因为返回类型而有两个不同的方法,因为代码无法推断出哪个应该是返回类型。

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

考虑如果我只调用dateStringGetter()而不赋返回值会发生什么。

我调用了哪个方法?