【问题标题】:How to pass 'out' parameter into lambda expressionC# - 如何将“out”参数传递给 lambda 表达式
【发布时间】:2010-10-28 18:01:06
【问题描述】:

我有一个带有以下签名的方法:

private PropertyInfo getPropertyForDBField(string dbField, out string prettyName)

在其中,我根据给定的dbField 找到关联的值prettyName。然后,我想查找名称为 prettyName 的所有属性(如果有),因此我尝试执行以下操作:

IEnumerable<PropertyInfo> matchingProperties =
    getLocalProperties().Where(prop =>
        prop.Name.Equals(prettyName)
    );

但是,这会产生以下错误:

不能在匿名方法、lambda 表达式或查询表达式中使用 ref 或 out 参数“prettyName”

在我尝试在Where lambda 参数中使用prettyName 的方法中,prettyName 肯定已初始化。如果prettyName 无法初始化为有效值,则我return。我可以在这里做些什么让我在 lambda 表达式中使用 prettyName 吗?

编辑:如果重要的话,我正在使用 .NET 3.5。

【问题讨论】:

  • 如何将您要放入 prettyName 的值存储到不同的变量中,以便您可以执行 prettyName = someval; 然后在您的匿名函数中使用 someval
  • 如接受的答案所示,您在标题中写的不是您想要做的,请更改它。

标签: c# linq lambda out-parameters


【解决方案1】:

只是为了澄清。可以在 lambda 中使用被调用方法的 ref/out 参数。

如果您指定参数的类型,您也可以使用 ref 或 out。这意味着将 prettyName 作为参数发送给 lambda。

(prop, ref string prettyName) => prop.Name.Equals(prettyName);

Where 子句只接受一个参数,即列表中的属性元素。这就是阻止您向 lambda 添加参数的原因。

不想给人们留下无法在 lambda 中使用这些参数的错误印象。你只是不能通过捕获来使用它们。

【讨论】:

  • Lee,由于某种原因,我无法让它工作。我使用的代码是 IEnumerable matchingProperties = getLocalProperties().Where((prop, ref string prettyName) => prop.Name.Equals(prettyName) ); ...但是它在“ref”上给出了错误(“不能在此范围内声明名为'prettyName'的局部变量,因为它会给已经在父范围或当前范围中使用的'prettyName'赋予不同的含义。
  • 或者您是说您仍然需要将 prettyName 重新分配给不同的字符串变量,但是您可以通过 ref 或 out 将其传入?
  • 是的,你必须给它起不同的名字。当我写这个答案时,我用一些没有给出有意义名称的示例代码进行了测试。所以我可能以不同的方式命名这两者。
  • 但是,我没有测试这是否会导致变量在您的某个时候神奇地改变。这就是为什么他们首先设置了限制。他们希望避免您导致变量稍后神奇地更改,因为当您将 arg 传递给委托时,它实际上持有对该 arg 的引用。由于可以通过将委托传递给其他地方或将其存储以供将来使用来随时调用委托,因此您的 arg 将比在其中声明的方法寿命更长。
【解决方案2】:

正如编译器错误所示,不允许在 lambda 表达式中使用 out 或 ref 参数。

为什么不直接使用副本?无论如何,lambda 都不想改变变量,所以我看不出有什么缺点。

string prettyNameCopy = prettyName;
var matchingProperties = getLocalProperties()
                        .Where(prop => prop.Name == prettyNameCopy);

或者,您可以使用局部变量(以评估适当的名称等),并在从方法返回之前分配out参数prettyName。如果方法中没有明显的分支,这可能会更具可读性。

【讨论】:

  • ...好吧,现在我只是觉得很傻。我正在寻找如何使用delegate 或一些疯狂的东西来做到这一点。谢谢!
  • 干杯。 delegate 不会有太大帮助,因为同样的限制也适用于匿名代表。
猜你喜欢
  • 1970-01-01
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 2022-01-19
相关资源
最近更新 更多