C# 无法识别泛型方法参数类型?

C# 无法识别泛型方法参数类型?,c#,generics,C#,Generics,这可能是由于我对泛型方法的糟糕理解,所以我提前道歉 我正试图编写一个继承自StreamWriter的csvWriter类。我希望它拥有的一种方法是使用数组或列表之类的集合,并使用String.Join将其更改为逗号分隔的字符串,然后像往常一样编写它。我原以为这会很简单,如果我使用方法重载的话,也会很简单,但我已经习惯了python,泛型的想法让我感觉更好,所以我尝试了一下 然而,我的尝试不起作用。这个方法似乎不知道传递给它的是什么类型,或者什么 类别: public class csvWrite

这可能是由于我对泛型方法的糟糕理解,所以我提前道歉

我正试图编写一个继承自StreamWriter的csvWriter类。我希望它拥有的一种方法是使用数组或列表之类的集合,并使用String.Join将其更改为逗号分隔的字符串,然后像往常一样编写它。我原以为这会很简单,如果我使用方法重载的话,也会很简单,但我已经习惯了python,泛型的想法让我感觉更好,所以我尝试了一下

然而,我的尝试不起作用。这个方法似乎不知道传递给它的是什么类型,或者什么

类别:

public class csvWriter : System.IO.StreamWriter
    {
        public csvWriter(string filename) : base(filename)
        {
        }

        public void WriteLineFromCollection<T>(T line)
        {
            string newLine = String.Join(",", line);
            base.WriteLine(newLine);
        }
    }
公共类csvWriter:System.IO.StreamWriter
{
公共csvWriter(字符串文件名):基(文件名)
{
}
公共无效WriteLineFromCollection(T行)
{
字符串换行符=string.Join(“,”行);
base.WriteLine(换行符);
}
}
电话号码:

using (var reader = new csvReader(filename_in))
using (var writer = new csvWriter(filename_out))
            {
                while (!reader.EndOfStream)
                {
                    string[] line = reader.ReadLine();
                    writer.WriteLineFromCollection<string[]>(line);
                }
                Console.Out.Write("PAUSE");
            }
使用(var reader=new csvReader(filename_in))
使用(var writer=new csvWriter(filename_out))
{
而(!reader.EndOfStream)
{
string[]line=reader.ReadLine();
writer.WriteLineFromCollection(行);
}
Console.Out.Write(“暂停”);
}
该文件没有让字符串充满逗号分隔的值,而是以“System.string[]”结尾。我想我实际上是在给它参数类型,而不是参数本身,但不知道为什么会这样。WriteLineFromCollection内部的调试器给了我一种冲突信息的感觉:
它说行的类型是string[],但当我尝试第[0]行时,它说“无法将[]索引应用于T类型的表达式。”

这是因为编译器选择了string。使用第二个参数
params object[]value
连接重载,所以您将字符串数组作为一个参数传递。要解决此问题,您可以向
WriteLineFromCollection
方法添加约束:

public void WriteLineFromCollection<T>(T line) where T : IEnumerable<string>
{
    string newLine = String.Join(",", line);
    base.WriteLine(newLine);
}
public void WriteLineFromCollection(T行),其中T:IEnumerable
{
字符串换行符=string.Join(“,”行);
base.WriteLine(换行符);
}

这将迫使编译器使用类型为
IEnumerable

的第二个参数选择重载。之所以发生这种情况,是因为编译器选择了字符串。将重载与第二个参数
params object[]value
连接,因此您将字符串数组作为一个参数传递。要解决此问题,您可以向
WriteLineFromCollection
方法添加约束:

public void WriteLineFromCollection<T>(T line) where T : IEnumerable<string>
{
    string newLine = String.Join(",", line);
    base.WriteLine(newLine);
}
public void WriteLineFromCollection(T行),其中T:IEnumerable
{
字符串换行符=string.Join(“,”行);
base.WriteLine(换行符);
}

这将迫使编译器使用类型为
IEnumerable

的第二个参数选择重载。我认为您应该尝试从
public void WriteLineFromCollection(T行)
更改为
public void WriteLineFromCollection(IList行)


如果您想支持索引,或者像Sergey提到的那样,添加一个约束。

我认为您应该尝试从
公共void WriteLineFromCollection(T行)
更改为
公共void WriteLineFromCollection(IList行)


如果您想支持索引,或者像Sergey提到的那样,请添加一个约束。

代码的方法没有什么问题,因为将要传递的唯一类型是String,这将导致滥用Genrics。。。
Prehapes您想为字符串类型编写一个extension方法,输出将是CSV格式的字符串吗?

您的代码方法没有什么问题,因为将要传递的唯一类型是字符串,这将导致滥用Genrics。。。
Prehapes您想为字符串类型编写一个extension方法,输出将是CSV格式的字符串吗?

在函数中,您使用
string[]
作为泛型类型参数,但函数除了它是一个对象(您没有类型限制)外,对传入的内容一无所知。因此,您的代码必须能够处理您可能通过的任何内容。现在,您可能希望它使用超负荷的
字符串。Join

public static string Join(
    string separator,
    IEnumerable<string> values
)
现在,由于这里的
params
关键字,您不必显式地传递
Object[]
,只需传递一组参数,它就会将其视为对象数组。例如,您可以这样做(不是说这是个好主意,因为它可能不是):

因此,当您传入
字符串[]
时发生的情况基本上等同于您这样做:

string.Join("," new object[] { line });
现在,重载所做的是,它将遍历对象数组中的每个项,并对其调用
ToString
,然后将结果合并在一起。在
字符串[]
上调用
ToString
将返回您所看到的
System.string[]
。这是
object.ToString()
的基本实现,它只返回类型名

显然,这不是你想要的。像这样的方法应该会奏效:

public void WriteLineFromCollection<T>(IEnumerable<T> line)
{
    string newLine = String.Join(",", line);
    base.WriteLine(newLine);
}
因此,现在,当您传入一个
T
的集合(它实现了
IEnumerable
,而
string[]
实现了这一点),它将被视为一个集合,而不是像以前那样隐式地包装在对象数组中。现在它在
T
集合中迭代并调用
ToString
,对于实际的
字符串
,它只返回
字符串本身。注意:如果您传递的不是
string
作为您的类型参数,那么您将得到
ToString
所做的任何事情,这可能只是类型名称。因此,如果希望在这里使用,您可能需要在自己的类中重写
ToString
,以执行一些合理的操作

当然,与仅仅内联调用
String.Join
相比,您实际上并没有从中获得太多好处,但这是不可能的
public void WriteLineFromCollection<T>(IEnumerable<T> line)
{
    string newLine = String.Join(",", line);
    base.WriteLine(newLine);
}
public static string Join<T>(
    string separator,
    IEnumerable<T> values
)
writer.WriteLineFromCollection(line);