我想知道如何将属性传递给方法。
当前,这是我的方法:
public static string Pick(this IFilePicker openFileService, Func<string> getCurrentFolder, Action<string> setCurrentFolder)
我用它来选择文件(带有对话框)。它会自动设置OpenFileDialog
的当前文件夹,调用getCurrentFolder
Func
。如果用户正确选择了文件,则会调用setCurrentFolder
操作。
我正在这样使用它:
Pick(openFileService, () => Settings.Current.Folder, str => Settings.Current.Folder = str);
但是对我来说,这看起来很麻烦。为什么使用2个参数代替1个?我可以通过财产。
但是如何?
我想这样称呼它:
Pick<Settings>(openFileService, x => x.Current.Folder);
那有可能吗?
注意设置。当前为单例。它是自动生成的。
答案 0 :(得分:2)
不幸的是,没有干净的方法可以做到这一点。我相信,您拥有的代码是最简单的方法。
您可以将方法更改为接受Expression<Func<string>>
,然后检查表达式树以获取属性...但是这样做会很费力,效率较低,并减少了编译时检查。您仍然需要传递() => Settings.Current.Folder
-它只会消除对最终参数的需求。
具体来说,在您的情况下,您需要构建一个表达式树,该树仍然访问Settings.Current
的getter,然后访问Folder
的setter。然后,您需要编译两个表达式树。
这都是可行的,但这是一项繁琐的工作。您当前的方法笨拙但简单。除非您需要做一个大的操作,否则我只会接受笨拙的操作。
假设Settings.Current
不变,另一种选择是传入属性的名称,因此您可以使用以下方式调用它:
Pick(openFileService, Settings.Current, nameof(Settings.Folder));
这仍然需要反思,并且会容易出错,IMO。
答案 1 :(得分:1)
属性不过是两个方法的封装,即get方法和set方法。因此,通过在委托中提供属性,您可以引用一个或另一个。这就是为什么您不能在委托中读取和并写入属性值的原因。
要读取一个属性,您肯定需要某种方法返回一个string
,并且不期望什么(即{ {1}})。当您要设置一个属性时,您将需要例外字符串。但没有返回任何东西(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
上调用Invoke
,您完全不清楚委托人的实际期望和返回的内容。即使我们可以确定它是某种Delegate
委托,也不清楚委托是否应该返回一个字符串,或者期望一个甚至两个都做,因此我们如何调用它。
答案 2 :(得分:1)
建议仅返回路径,但实际上var $categories = $('.menu-item-category');
$categories.each(function() {
var $this = jQuery(this);
if ($this.text().includes ('Offers') {
$('.m3-item').addClass('menu-offers');
}
});
方法需要返回文件以及设置路径。
我将向Pick()
添加一个重载或新方法,该方法将读取/设置Settings.Current对象中的路径,因此调用不必关心“当前”路径来自何处。我假设您有90%以上的时间会始终读OpenFileService
并写回Settings.Current.Path
,所以最好使Settings.Current.Path
处理此问题,而不是每次调用它吗?