在PowerShell中使用带有重载算术运算符的自定义.NET类

时间:2012-10-18 21:06:23

标签: c# .net powershell operators

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

所以在C#中我有“+”运算符重载了三个不同的签名。签名明确地是:

  • A + Double
  • Double + A
  • A + A

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

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

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

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

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

更新: Dugas 将其钉住。但是我一路上学到了别的东西,想把它贴在这里。

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

如果操作的结果为NULL,则op_Addition运算符将抛出“Object reference not set ...”错误,而不是返回NULL。我假设在PowerShell尝试使用错误的重载运算符并且在执行类型转换时遇到问题时创建了NULL引用,从而误解了这个错误。

我重新考虑了对象的A + A案例,当求和时,返回A类的另一个对象实例,一切都很好。

总结一下,如果a1,a2和a3都是A类的实例,d是Double,如果a1 + a2 = NULL且a1 + a3 = aX(其中aX是A类的新实例)那么..

  • d + a1#失败,因为PowerShell没有看到Double的运算符,而A类和A类都无法转换为Double。
  • a1 + d#按预期工作
  • a1 + a2#失败。引发“对象引用未设置...”错误,因为结果为NULL。
  • a1 + a3#按预期工作。

感谢您指导我正确的方向!

1 个答案:

答案 0 :(得分: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”类型。

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