当前位置: 首页 > 知识库问答 >
问题:

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

林星华
2023-03-14

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

所以在C#中,我用三个不同的签名重载了“”运算符。显式签名是:

    一个双人间 < li >双A 答:答:答

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

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

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

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

有人成功地使用了具有不同签名的重载类操作符吗?或者这种行为会破坏PowerShell的基本设计目标吗?

更新:杜加斯成功了。但我在这过程中确实学到了一些东西,并想在这里发布。

当我为类A定义加法时,我定义了它,这样添加类A的两个实例将产生类A的一个新实例或者产生一个空值。(这是我糟糕的设计,因为加法确实应该关闭。换句话说,理想情况下,加法应该总是产生可以被另一个加法运算符处理的结果。)在C#中,这不是问题,因为我从不一次添加两个以上的对象,并且在检查结果时检查是否为NULL。

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

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

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

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

谢谢你把我引向正确的方向!

共有1个答案

孙福
2023-03-14

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

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 = New-Object ClassLibrary1.Class1
($a + 0) -eq 'a' # Was True
($a + $a) -eq 'c' # Was True

调用重载:

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

给出错误:

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

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

 类似资料:
  • 问题内容: 给定以下JavaScript“类”定义,这是我想到此问题的最佳方式: 以及以下测试设置代码: 有什么方法可以使用加法运算符隐式创建为对象,如下所示… 而不是求助于… 如果不是,那么在此领域中关于通过算术运算符使自定义数字JavaScript对象可组合的最佳实践建议是什么? 问题答案: 据我所知,JavaScript(至少现在已经存在)不支持运算符重载。 我能建议的最好的方法是使用一个类

  • 自定义运算符 struct Vector2D { var x = 0.0 var y = 0.0 } infix operator +++ extension Vector2D { static func +++ (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left

  • 我试图为一个2D表示向量的类定义“-=”和“-”,但我得到了这个错误: vecteur2d.cc:131:7:错误:没有可行的重载“-=”VEC1-=VEC2;

  • 运算符是处理数据的基本方法,用来从现有的值得到新的值。JavaScript 提供了多种运算符,覆盖了所有主要的运算。 概述 JavaScript 共提供10个算术运算符,用来完成基本的算术运算。 加法运算符:x + y 减法运算符: x - y 乘法运算符: x * y 除法运算符:x / y 指数运算符:x ** y 余数运算符:x % y 自增运算符:++x 或者 x++ 自减运算符:--x

  • Rust可以让我们对某些运算符进行重载,这其中大部分的重载都是对std::ops下的trait进行重载而实现的。 重载加法 我们现在来实现一个只支持加法的阉割版复数: use std::ops::Add; #[derive(Debug)] struct Complex { a: f64, b: f64, } impl Add for Complex { type Outpu

  • 假设: 2的补码形式的32位有符号整数 true和false是值为1和0的整数 java运算符 你能实现像<代码>