C# 在泛型方法中调用重载方法
看起来Test.Write总是试图调用BinaryWriter.Write(bool)。有什么建议吗?重载解析发生在编译时,在这种情况下,对T一无所知,因此不适用重载C# 在泛型方法中调用重载方法,c#,C#,看起来Test.Write总是试图调用BinaryWriter.Write(bool)。有什么建议吗?重载解析发生在编译时,在这种情况下,对T一无所知,因此不适用重载 1. The best overloaded method match for 'System.IO.BinaryWriter.Write(bool)' has some invalid arguments 2. Argument 1: cannot convert from 'T' to 'bool' 类测试 { 公共二进制编
1. The best overloaded method match for 'System.IO.BinaryWriter.Write(bool)' has some invalid arguments
2. Argument 1: cannot convert from 'T' to 'bool'
类测试
{
公共二进制编写器内容{get;private set;}
公共测试写入(T数据)
{
内容。写入((动态)数据);
归还这个;
}
}
当然,这也会带来一些问题。例如,如果您将DateTime发送给该方法,则appliction将很好地编译。但是,它会抛出异常。在您的写入方法中,
T
是泛型的,这意味着T
可以是任何东西,但BinaryWriter.write
不接受泛型重载。所以你不能那样做。你不能那样做
由于
T
的实际类型在编译时未知,编译器无法找到合适的Write
重载,并尝试调用第一个找到的重载。没有重载,可以使用任何类型的T
(例如,Write(object)
)调用重载。这是可能的,但不能使用一般约束。您可以尝试使用反射,并根据T
的类型获得适当的Write
方法重载版本
使用构造函数中的流
初始化您的BinaryWriter
,然后使用反射,如下所示:
class Test
{
public BinaryWriter Content { get; private set; }
public Test Write<T>(T data)
{
Content.Write((dynamic)data);
return this;
}
}
Test writer;
using (var fs = new FileStream("sample.txt", FileMode.Open))
{
writer = new Test(fs);
writer = writer.Write(232323);
writer = writer.Write(true);
writer = writer.Write(12);
}
using (var fs = File.Open("sample.txt", FileMode.Open))
{
var reader = new BinaryReader(fs);
Console.WriteLine(reader.ReadInt32()); // 232323
Console.WriteLine(reader.ReadBoolean()); // true
Console.WriteLine(reader.ReadByte()); // 12
}
这个方法非常冗长,但它是唯一一个提供Arment类型编译时检查的方法,而且在选择重载和编译时时时性能最好。此外,这些方法可能是内联的
在这种情况下,我通常使用T4脚本,该脚本基于反射生成上述代码。创建一个TT文件,枚举二进制编写器的写重载,生成代码
也许它可以解决问题,但这种方法很危险,而且容易出现异常。实际上,在这种情况下,它不需要是泛型方法。最烦人的是,我永远看不到
-1
的解释。
class Test
{
public BinaryWriter Content { get; private set; }
public Test(Stream stream)
{
Content = new BinaryWriter(stream);
}
public Test Write<T>(T data)
{
var method = typeof (BinaryWriter).GetMethod("Write", new[] {data.GetType()});
if (method != null)
{
method.Invoke(Content, new object[] { data });
}
// here you might want to throw an exception if method is not found
return this;
}
}
Test writer;
using (var fs = new FileStream("sample.txt", FileMode.Open))
{
writer = new Test(fs);
writer = writer.Write(232323);
writer = writer.Write(true);
writer = writer.Write(12);
}
using (var fs = File.Open("sample.txt", FileMode.Open))
{
var reader = new BinaryReader(fs);
Console.WriteLine(reader.ReadInt32()); // 232323
Console.WriteLine(reader.ReadBoolean()); // true
Console.WriteLine(reader.ReadByte()); // 12
}
public Test Write (bool data)
{
Content.Write(data);
return this;
}
public Test Write (byte data)
{
Content.Write(data);
return this;
}
public Test Write (byte[] data)
{
Content.Write(data);
return this;
}
public Test Write (char data)
{
Content.Write(data);
return this;
}
public Test Write (char[] data)
{
Content.Write(data);
return this;
}
// ...