在C#重载方法中将string []与IEnumerable <t>和字符串关联到T.

时间:2017-02-11 12:14:08

标签: c# generics overloading

我创建了2个静态重载方法,用于使用System.IO.StreamWriter写入文件。第一种方法应该写一行。第二种方法应该写出很多行。我试图使它成为通用的,因此它不仅可以用于字符串(即其他原始类型,如intfloatbool或任何带有ToString()的对象

public static void WriteLine<T>(string path, T t, bool append = false)
{
    using (var file = new StreamWriter(path, append))
    {
        file.WriteLine(t.ToString());
    }
}

public static void WriteLine<T>(string path, IEnumerable<T> ts, bool append = false)
{
    using (var file = new StreamWriter(path, append))
    {
        foreach (var t in ts)
        {
            file.WriteLine(t.ToString());
        }
    }
}

但是,我的方法似乎有问题。例如,假设我有以下代码:

string pathString = @"C:\temp";
const string fileName = @"test.txt";
string path = Path.Combine(pathString, fileName);

const bool append = true;

string line = "single";
WriteLine(path, line, append);

string[] lines = { "first", "second", "third" };
WriteLine(path, lines, append);

WriteLine的两次调用都解析为我的两种方法中的第一种。我希望第一次调用WriteLine会解析为第一种方法,因为我传递了一个字符串,第二次调用WriteLine会解析为第二种方法,因为我传递了一串字符串。但事实并非如此。

另外,如果我删除了第一个方法public static void WriteLine<T>(string path, T t, bool append = false),那么对WriteLine的两次调用都会解析为public static void WriteLine<T>(string path, IEnumerable<T> ts, bool append = false),并得到以下输出:

s
i
n
g
l
e
first
second
third

此外,如果我删除了第二种方法public static void WriteLine<T>(string path, IEnumerable<T> ts, bool append = false),那么对WriteLine的两次调用都会解析为public static void WriteLine<T>(string path, T t, bool append = false),并得到以下输出:

single
System.String[]

如何更正我的静态重载WriteLine方法,以便将string[]作为参数传递,使用WriteLine调用IEnumerable<T>方法并将string作为参数使用WriteLine调用T方法?

此时,我不确定它是否可行。如果不是,那么我想我只需要将方法重命名为WriteLine(T t)WriteLines(IEnumerable<T> ts)

1 个答案:

答案 0 :(得分:1)

您没有在方法中的任何位置使用T类型。您正在呼叫t.ToString(),但在ToString()上定义了object,因此您无需知道T

因此,您可以采取objectIEnumerable创建非通用方法。此时,如果你不想打印单个字符,你还需要第三次重载string,但你可以用最后一个来实现第一个。

public static void WriteLine(string path, object o, bool append = false)
{
    WriteLine(path, o.ToString(), append);
}

public static void WriteLine(string path, string s, bool append = false)
{
    using (var file = new StreamWriter(path, append))
    {
        file.WriteLine(s);
    }
}

public static void WriteLine(string path, IEnumerable e, bool append = false)
{
    using (var file = new StreamWriter(path, append))
    {
        foreach (var o in e)
        {
            file.WriteLine(o.ToString());
        }
    }
}

现在,正如评论中所提到的,我不是这个API的粉丝,我建议您使用重命名(WriteLineWriteLines)来突出显示两者之间的功能差异方法,但这种方法对于其他方法可能是值得的,因此仍应作为答案提供。