将属性传递给方法进行读/写

  • 本文关键字:方法 属性 c# .net wpf
  • 更新时间 :
  • 英文 :


我想知道如何将属性传递给方法。

目前,这是我的方法:

public static string Pick(this IFilePicker openFileService, Func<string> getCurrentFolder, Action<string> setCurrentFolder)

我用它来拾取文件(带有对话框(。它自动设置调用getCurrentFolderFuncOpenFileDialog的当前文件夹。如果用户正确地选择了一个文件,那么就会调用setCurrentFolder操作。

我是这样使用的:

Pick(openFileService, () => Settings.Current.Folder, str => Settings.Current.Folder = str);

但我觉得它很麻烦。为什么用2个参数而不是1个?我可以路过这里。

但是怎么做呢?

我想这样称呼它:

Pick<Settings>(openFileService, x => x.Current.Folder);

这可能吗?

注:设置。当前是一个单点。它是自动生成的。

不幸的是,没有一种干净的方法可以做到这一点。我相信,您所拥有的代码是最简单的方法。

您可以更改方法以接受Expression<Func<string>>,然后检查表达式树以获取属性。。。但这将是一项艰巨的工作,效率较低,并且会减少编译时的检查。您仍然需要传递() => Settings.Current.Folder——这只会消除对最终参数的需要。

具体来说,在您的情况下,您需要构建一个表达式树,该树仍然访问Settings.Current的getter,但随后访问Folder的setter。然后,您需要编译这两个表达式树。

这一切都是可行的,但这是一项艰巨的工作。你目前的方法虽然笨拙但很简单。除非你需要做这件事,否则我会接受这些笨拙的行为。

假设Settings.Current没有更改,另一个选项是传入属性的名称,所以您可以用调用它

Pick(openFileService, Settings.Current, nameof(Settings.Folder));

这仍然需要反思,而且有点容易出错

属性只不过是由两个方法组成的包,一个是get方法,另一个是set方法。因此,通过在委托中提供属性,可以引用其中一个或另一个。这就是为什么您不能在委托中读取写入属性值的原因。

为了读取属性,您肯定需要一些返回string不期望任何内容(即Func<string>(的方法。当您想设置一个属性时,您需要超出字符串的东西。但不返回任何内容(Action<string>(。

此外,让我们看看如何定义委托

Pick(string file, Delegate readAndWriteDelegate)
{
// what can you do with the delegate? You don´t know if you can provide a string or if it returns one
// do I have to use this?
readAndWriteDelegate(file);
// or this?
var result = readAndWriteDelegate();
// or even this?
var result = readAndWriteDelegate(file);
// in fact I could even use this
MyClass m = readAndWriteDelegate(3);
}

我只是使用现有的Delegate来表明,甚至没有办法声明您的委托并提供其类型安全性。

假设上面的代码甚至不会编译,因为我们必须在Delegate上调用Invoke,您会发现完全不清楚您的委托实际期望的内容和返回的内容。即使我们可以确定它是某种string委托,也不清楚委托是否应该返回字符串或期望返回一个字符串,甚至同时返回两个字符串,因此我们如何调用它。

建议只返回路径,但实际上Pick()方法需要返回文件并设置路径。

我会在OpenFileService中添加一个重载或新方法,它将读取/设置Settings.Current对象中的Path,这样调用就不必关心"Current"路径来自哪里。我假设90%以上的时间你总是读Settings.Current.Path并写回Settings.Current.Path,所以最好让OpenFileService处理这个问题,而不是每次调用它?

最新更新