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

C# 在PowerShell中使用带有重载算术运算符的自定义.NET类,c#,.net,powershell,operators,C#,.net,Powershell,Operators,我在C#中定义了一个类(称为class a),并重载了它的一些算术运算符。让我们关注加法操作符(尽管我希望其他操作符的行为类似)。我已经设置了类A,这样我可以向它添加标量(即单个双精度值),我可以将它添加到标量,或者我可以将两个实例添加到一起 在C#中,我用三个不同的签名重载了“+”操作符。明确地说,签名是: A+双倍 双+A A+A 当我在PowerShell中使用该类时,它只识别三个重载中的一个。因此,在PowerShell中,我可以执行+Double,但其他两个表达式会导致错误 当我在

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

在C#中,我用三个不同的签名重载了“+”操作符。明确地说,签名是:

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

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

我怀疑这是故意的。我喜欢PowerShell,但它与C#有很大的不同,我希望它只允许重载运算符使用一个签名(根据我到目前为止对它的了解),并且表达式的左侧成员决定要执行的加法类型。有人能证实吗

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

是否有人成功地使用了具有不同签名的重载类运算符,或者这种行为会破坏PowerShell的基本设计目标

更新:Dugas搞定了。但我确实在这一过程中学到了一些东西,我想把它贴在这里

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

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

我为对象重新运行了A+A用例,当求和时,返回另一个类A的对象实例,一切都很好

总之,如果a1、a2和a3都是类A的实例,而d是双精度的,如果a1+a2=NULL,a1+a3=aX(其中aX是类A的新实例),则

  • d+a1#失败,因为PowerShell没有看到接受A类的Double的运算符,并且A类无法转换为Double
  • a1+d#按预期工作
  • a1+a2#失败。抛出“对象引用未设置…”错误,因为结果为空
  • a1+a3#按预期工作

谢谢你给我指引了正确的方向

出于好奇,我测试了这个。我创建了这样一个类:

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”类型


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

调用正确的运算符方法是C#编译器的一项功能,因此我一点也不奇怪,这在PowerShell中不起作用。我很确定这在CLS中是标准化的。在所有方面都是正确的。看完你的帖子后,我又回去试了一些例子。事实证明,我试图添加到一起的两个特定类实例返回NULL。PowerShell在op_Addition方法中引发“对象引用未设置为实例…”错误。因为我知道两个输入都不是NULL,所以我假设NULL对象错误是由于PowerShell应用了错误的重载,并且未能将对象转换为兼容类型造成的。