需要找到一种方法,该方法将具有可变数量的参数(见下文MyLog
)的委托动作传递给另一种方法(见{{1 }}放在ExtractToDirectory
下面。
我有一个Log方法:
MyLog
然后在同一WinForm类中进一步调用:
public static void MyLog(string variable, params object[] args)
{
textBoxLog.AppendText(string.Format(message, args) + Environment.NewLine);
}
带有方法的静态类:
private void buttonInstall_Click(object sender, EventArgs e)
{
using (Stream zipStream = <Get stream from Resources>)
using (ZipArchive zip = new ZipArchive(zipStream))
zip.ExtractToDirectory(@"Z:\", MyLog);
}
问题出在public static class ZipFileExtensions
{
public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, Action<string, params object[]> myLog)
{
myLog("Starting {0} extraction", source.Name);
}
}
的声明上。
ExtractToDirectory
关键字带有下划线并带有错误:期望的类型。
我试图不放置参数,但是VS期望对象数组而不是我需要的可变长度参数。
有任何线索吗?
答案 0 :(得分:2)
删除“ params”关键字并将其设置为Action<string, object[]>
,它可能会编译。 params
只是语法糖。函数本身不是“可变的”。它只是采用object []类型的第二个参数。
当然,Action<string, object[]>
出于所有目的都不会表现为“杂色性”,它将希望您始终提供new []{..}
。动作/功能委托不支持params
。不过,您可以创建自己的专业代表:
using System;
public delegate void LogAction(string template, params object[] args);
public static void Log(string a, params object[] args)
{
System.Console.WriteLine(a,args);
}
public static void Main()
{
var act = new Action<string,object[]>(Test.Log);
act("fooo {0} {3}", new object[]{1, 3, 4, 5});
var myAct = new LogAction(Test.Log);
myAct("fooo {0} {3}", 1, 3, 4, 5);
}
答案 1 :(得分:0)
在quetzalcoatl answer之后,我结束了:
public partial class MainForm : Form
{
public delegate void LogAction(string message, params object[] args);
public void Logger(string message, params object[] args)
{
if (args != null)
textBoxLog.AppendText(string.Format(message, args) + Environment.NewLine);
else
textBoxLog.AppendText(message + Environment.NewLine);
Application.DoEvents();
}
private void buttonInstall_Click(object sender, EventArgs e)
{
Logger("Button clicked");
using (Stream zipStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Resources.test.zip"))
using (ZipArchive zip = new ZipArchive(zipStream))
zip.ExtractToDirectory(Program.DestinationInstallation, Logger);
}
public static class ZipFileExtensions
{
public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, MainForm.LogAction myLogger)
{
int number = 20180803;
myLogger("{0} >> {1} (ok)", DateTime.Now, number);
}
}
非常感谢您的帮助。