【问题标题】:Can I set the value of decimal variable within an extension method? [duplicate]我可以在扩展方法中设置十进制变量的值吗? [复制]
【发布时间】:2016-01-11 14:06:00
【问题描述】:

我创建了一个void 扩展方法,可以与decimal 数据类型一起使用。我希望能够在方法范围内修改this 参数变量。这是我的扩展方法的代码:

public static void SetAndConvertIfHasValue(this decimal assignTo, double? valueToAssign)
{
    if (valueToAssign.HasValue)
        assignTo = (decimal)valueToAssign.Value;
    else
        assignTo = 0m;
}

但是,当我调用它时:

data.MyDecimalToSet.SetAndConvertIfHasValue(nullableDouble);

data.MyDecimalToSet 没有设置为nullableDouble 中的值(如果有的话)。

在调试中,如果我进入扩展方法,assignTo 会更改为正确的值,此更改不会冒泡到data.MyDecimalToSet

此时我决定使用标准方法而不是扩展方法来解决这个问题,但是我很好奇为什么这不起作用?以及是否有解决方法,或者根本不可能?

【问题讨论】:

  • 如果你想发疯,你可以创建一个扩展方法,除了 double? 之外,还需要一个 Expression<decimal>,打开它并使用一点反射设置属性。然后你会在基础对象而不是属性上调用它,就像这样:data.SetAndConvertIfHasValue(d => d.MyDecimalToSet, nullableDouble)。它更丑更慢,但它有效!

标签: c# extension-methods


【解决方案1】:

这不起作用,因为当您将变量传递给方法时,会传递该变量的副本。当您对该副本进行操作时,您只会更改该副本。

请注意,无论变量是引用类型还是值类型,都会发生这种情况。但是,如果您传递引用类型,则可以更改引用类型的内容,因为传递给方法的引用将被复制,但仍会引用原始对象。

decimal是一个值类型,所以最后一点不适用于它。)

如果您使用标准方法,那么您的做法是正确的。

【讨论】:

  • 我以为是这个原因。我尝试将其作为 ref 传递,但扩展方法不支持。
  • 不要在这些解释中使用“stack”和“heap”,因为它们是实现细节。复制和引用语义会更好。无论如何,即使这里使用了引用类型,也会出现同样的问题,因为您无法修改传入的变量/属性/字段,除非它们使用refout 传递。因此,它与值类型与引用类型无关。
  • @siride 我想,像ref,你不能在扩展方法中使用out
  • @GaryEmery:正确(因为在 CLR 中,refout 是完全相同的——只有在 C# 中,编译器才强制与 OutAttribute 有所不同)。不过,更重要的是,您不能将属性传递给扩展方法或 ref/out 等任何方法。
  • @siride 我已经稍微纠正了我的答案。
猜你喜欢
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 2013-07-16
  • 2014-07-11
  • 2012-10-18
  • 1970-01-01
  • 2013-07-09
  • 2011-08-21
相关资源
最近更新 更多