5

我在 C# 中定义了一个类(称为 A 类)并为它重载了一些算术运算符。让我们关注加法运算符(尽管我希望其他运算符的行为类似)。我已经设置了 A 类,这样我就可以向它添加一个标量(即单个 Double 值),我可以将它添加到一个标量,或者我可以将 A 的两个实例加在一起。

因此,在 C# 中,“+”运算符重载了三个不同的签名。明确的签名是:

  • A + 双
  • 双 + A
  • 一个+一个

当我在 PowerShell 中使用该类时,它只识别三个重载之一。因此在 PowerShell 中我可以执行 A + Double 但其他两个表达式会导致错误。

当我在 A 的实例上使用 Get-Member Cmdlet 时,它看起来好像“看到”了所有三个重载,但只尊重列表中的第一个重载。

我怀疑这是设计使然。我喜欢 PowerShell,但它与 C# 非常不同,我希望它只允许重载运算符的一个签名(基于我到目前为止所了解的内容),并且表达式的左侧成员确定添加的类型履行。任何人都可以确认吗?

我的工作是在 C# 中为类编写一些更详细的静态方法(如“AddScalar”和“AddA”方法)。在 PowerShell 中,我会调用这些命名方法,而不是使用“+”运算符。这应该可以正常工作,但是让 PowerShell 根据添加的内容使用适当的“+”定义会很好。

有没有人使用具有不同签名的重载类运算符取得任何成功,或者这种行为会破坏基本的 PowerShell 设计目标?

更新: 杜加斯做到了。但我确实在此过程中学到了其他东西,并想把它贴在这里。

当我为类 AI 定义添加时,它定义为添加两个类 A 的实例将产生一个新的类 A 实例或产生一个 NULL。(这对我来说是糟糕的设计,因为加法确实应该关闭。换句话说,理想情况下,加法应该总是产生可以被另一个加法运算符操作的东西。)在 C# 中这不是问题,因为我从来没有添加更多一次超过两个对象,并在我检查结果时检查 NULL。

如果操作的结果为 NULL,PowerShell 不会返回 NULL,而是会为 op_Addition 运算符引发“未设置对象引用...”错误。我误解了这个错误,假设当 PowerShell 尝试使用错误的重载运算符并且在执行类型转换时遇到问题时正在创建 NULL 引用。

我为对象重新运行了 A + A 案例,这些对象在求和时会返回 A 类的另一个对象实例,并且一切正常。

总而言之,如果 a1、a2 和 a3 都是 A 类的实例并且 d 是 Double 并且如果 a1 + a2 = NULL 并且 a1 + a3 = aX(其中 aX 是 A 类的新实例),那么...

  • d + a1 # 失败,因为 PowerShell 没有看到使用 Class A 的 Double 运算符,并且 Class A 不能转换为 Double。
  • a1 + d # 按预期工作
  • a1 + a2 # 失败。引发“未设置对象引用...”错误,因为结果为 NULL。
  • a1 + a3 # 按预期工作。

感谢您引导我朝着正确的方向前进!

4

1 回答 1

2

出于好奇,我对此进行了测试。我创建了一个这样的类:

namespace ClassLibrary1
{
 public class Class1
 {
  public static string operator +(Class1 class1, double d)
  {
   return "a";
  }

  public static string operator +(double d, Class1 class1)
  {
   return "b";
  }

  public static string operator +(Class1 class1, Class1 class12)
  {
   return "c";
  }
 }
}

我能够调用以 Class1 作为第一个参数的两个重载,但不能调用以 double 作为第一个参数的重载。我不知道您为什么不能调用 A + A 的重载,也许是因为除了调度正确的运算符重载之外的其他原因?

$a = New-Object ClassLibrary1.Class1
($a + 0) -eq 'a' # Was True
($a + $a) -eq 'c' # Was True

调用重载:

([double]0 + $a) -eq 'b'

报错:

无法将“ClassLibrary1.Class1”类型的“ClassLibrary1.Class1”值转换为“System.Double”类型。

所以我假设你可以调用不同的运算符重载,只要第一个参数是运算符重载的类型?

于 2012-10-18T21:46:50.537 回答