Вы также должны сохранить имя делегата или метода, который вы хотите вызвать, как строку в классе.
Я использовал это, поскольку хотел настроить, какую функцию вызывать после загрузки файла через ftp в файле конфигурации, т. Е. Различные конфигурации загрузки ftp по-разному обрабатывают загруженный файл, вызывая настроенный метод (делегат).
public delegate string ProcessDownloadedFile(string filename);
//HACK: Cannot serialise delegates.
public string ProcessDownloadFileMethod { get; set; }
//HACK: Cannot serialise delegates.
[XmlIgnore]
public ProcessDownloadedFile ProcessFile { get; set; }
Тогда, когда вы захотите использовать делегата, в данном случае после того, как я скачал файл. Я создаю делегата, используя строку, которую я сохранил в сериализованном файле конфигурации.
//Create the delegate method if it has been set.
if (!String.IsNullOrEmpty(ftpReceive.ProcessDownloadFileMethod) && ftpReceive.ProcessFile == null)
{
//Create the delegate.
Type t = typeof(FTPTransfer);
ftpReceive.ProcessFile = (FTPTransfer.ProcessDownloadedFile) Delegate.CreateDelegate(typeof(FTPTransfer.ProcessDownloadedFile), t.GetMethod(ftpReceive.ProcessDownloadFileMethod));
}
Так что в идеале вы хотите сохранить имя функции / делегата, которую вы хотите вызвать, как строку, а затем создать ее из строки во время выполнения с помощью отражения.
Надеюсь, это поможет.
Или, если вызываемые методы будут когда-либо существовать только в одном классе, вы можете упростить его, обернув свойства, чтобы упростить его.
//HACK: Cannot serialise delegates.
public string ProcessDownloadFileMethod { get; set; }
//HACK: Cannot serialise delegates.
private ProcessDownloadedFile _processFile;
[XmlIgnore]
public ProcessDownloadedFile ProcessFile
{
get
{
if (_processFile == null && !String.IsNullOrEmpty(ProcessDownloadFileMethod))
{
Type t = this.GetType();
this._processFile = (ProcessDownloadedFile) Delegate.CreateDelegate(typeof(ProcessDownloadedFile), t.GetMethod(this.ProcessDownloadFileMethod));
}
return _processFile;
}
set
{
if (value != null)
{
ProcessDownloadFileMethod = value.Method.Name;
} else {
ProcessDownloadFileMethod = null;
}
_processFile = value;
}
}
Чтобы действительно сделать это настраиваемым, возможно, было бы целесообразно включить класс / тип, а также имя функции / метода для создания делегата.