无法为 StreamWriter 应用“using”的新语法
Unable to apply the new syntax of `using` for StreamWriter
MSDN about using
上出现了新语法。喜欢就开始应用了
而不是
using (MemoryStream memory = new MemoryStream())
{
using (CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write))
{
using (StreamWriter writer = new StreamWriter(crypto))
{
writer.Write(text);
}
}
}
我可以走了
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using (StreamWriter writer = new StreamWriter(crypto))
writer.Write(text);
但是,我无法让最后一部分以新的方式工作。出于某种原因,StreamWriter
不允许我这样做。
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
我真的不明白为什么。链接文章中可能有技术解释,因为他们讨论了要求和限制。遗憾的是,我根本看不出他们说的是什么,暗示的是什么。
根据 Skeety 的要求 - 完整的可重现样本。
public void Test()
{
string text = "hakuna matata";
string code = "1234567890abcdef";
byte[] key = Encoding.ASCII.GetBytes(code);
byte[] iv = key[..16];
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
//writer.Flush();
//using (StreamWriter writer = new StreamWriter(crypto))
// writer.Write(text);
string output = Convert.ToBase64String(memory.ToArray());
}
在您的旧代码下,您的所有资源,包括 StreamWriter
和 CryptoStream
,都在其 using
块的末尾隐式处理。处理后,任何待处理的内容都会刷新到 MemoryStream
。因此,当您检查 MemoryStream
在 这些 using
块的末尾时,它会被正确填充。
在您的新代码中,新的 using
语法意味着资源仅在 enclosing 块的末尾处理——在本例中,父方法.因此,当您在同一方法中检查 MemoryStream
时,您是在 before StreamWriter
和 CryptoStream
已被处置,因此 before 它们的内容已经刷新到 MemoryStream
.
为了演示,在读取 MemoryStream
之前在 StreamWriter
上调用 Dispose
将恢复正确的行为:
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
writer.Dispose()
string output = Convert.ToBase64String(memory.ToArray());
也就是说,我不建议这样做,因为您将显式 Dispose
调用与 using
.
生成的隐式调用混合在一起
或者,您可以从 outer 方法中使用 MemoryStream
,从而确保 inner 方法在执行结束时释放其资源:
public void Test()
{
var memory = TestInner();
string output = Convert.ToBase64String(memory.ToArray());
}
private MemoryStream TestInner()
{
string text = "hakuna matata";
string code = "1234567890abcdef";
byte[] key = Encoding.ASCII.GetBytes(code);
byte[] iv = key[..16];
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
return memory;
}
但是,在这种情况下,为了清楚起见,我更愿意使用旧的 using
块。
MSDN about using
上出现了新语法。喜欢就开始应用了
而不是
using (MemoryStream memory = new MemoryStream())
{
using (CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write))
{
using (StreamWriter writer = new StreamWriter(crypto))
{
writer.Write(text);
}
}
}
我可以走了
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using (StreamWriter writer = new StreamWriter(crypto))
writer.Write(text);
但是,我无法让最后一部分以新的方式工作。出于某种原因,StreamWriter
不允许我这样做。
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
我真的不明白为什么。链接文章中可能有技术解释,因为他们讨论了要求和限制。遗憾的是,我根本看不出他们说的是什么,暗示的是什么。
根据 Skeety 的要求 - 完整的可重现样本。
public void Test()
{
string text = "hakuna matata";
string code = "1234567890abcdef";
byte[] key = Encoding.ASCII.GetBytes(code);
byte[] iv = key[..16];
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
//writer.Flush();
//using (StreamWriter writer = new StreamWriter(crypto))
// writer.Write(text);
string output = Convert.ToBase64String(memory.ToArray());
}
在您的旧代码下,您的所有资源,包括 StreamWriter
和 CryptoStream
,都在其 using
块的末尾隐式处理。处理后,任何待处理的内容都会刷新到 MemoryStream
。因此,当您检查 MemoryStream
在 这些 using
块的末尾时,它会被正确填充。
在您的新代码中,新的 using
语法意味着资源仅在 enclosing 块的末尾处理——在本例中,父方法.因此,当您在同一方法中检查 MemoryStream
时,您是在 before StreamWriter
和 CryptoStream
已被处置,因此 before 它们的内容已经刷新到 MemoryStream
.
为了演示,在读取 MemoryStream
之前在 StreamWriter
上调用 Dispose
将恢复正确的行为:
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
writer.Dispose()
string output = Convert.ToBase64String(memory.ToArray());
也就是说,我不建议这样做,因为您将显式 Dispose
调用与 using
.
或者,您可以从 outer 方法中使用 MemoryStream
,从而确保 inner 方法在执行结束时释放其资源:
public void Test()
{
var memory = TestInner();
string output = Convert.ToBase64String(memory.ToArray());
}
private MemoryStream TestInner()
{
string text = "hakuna matata";
string code = "1234567890abcdef";
byte[] key = Encoding.ASCII.GetBytes(code);
byte[] iv = key[..16];
using Aes aes = Aes.Create();
using ICryptoTransform transform = aes.CreateEncryptor(key, iv);
using MemoryStream memory = new MemoryStream();
using CryptoStream crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write);
using StreamWriter writer = new StreamWriter(crypto);
writer.Write(text);
return memory;
}
但是,在这种情况下,为了清楚起见,我更愿意使用旧的 using
块。