gpt4 book ai didi

C# 自定义一元运算符重载

转载 作者:行者123 更新时间:2023-11-30 19:17:04 24 4
gpt4 key购买 nike

C# 类是否从基类继承自定义运算符?我正在尝试以下代码:

class Person
{
public int Age;

public static Person operator ++(Person p)
{
p.Age++;
return p;
}
}

class Agent : Person { }

static void Main(string[] args)
{
Person p = new Person { Age = 23 };
Console.WriteLine ( "Before increment : {0}" , p.Age );

p++;
Console.WriteLine("After increment : {0}", p.Age);

Agent agent = new Agent { Age = 25 };
Console.WriteLine("Before increment : {0}", agent.Age);

agent++;
Console.WriteLine("After increment : {0}", agent.Age);

}

编译器告诉我,他不能显式地从 Person 转换为 Agent。

我试过了:

Agent agent = new Agent();
Person person = agent ++

但出现相同的编译器消息。

最佳答案

您遇到的问题不是基于运算符是否被继承,而是由于运算符的返回类型。

但是,在分配运算符的情况下,运算符的返回类型会有问题

表达式x++

x = x + 1

在您的情况下,您要返回一个 Person 并尝试将其分配给一个 Agent。写出来会是

agent.Age++;
agent = (Person)agent; //the cast is implicit and a result of the return type

您只能分配给更通用的类型。因此,将 Agent 分配给 Person 会起作用,这就是为什么编译器将允许返回类型是实现类型的特化(如下例所示)。

你可以通过一些泛型技巧来完成你正在寻找的东西

class Person<T> where T : Person<T>, new()
{
public int Age;

//taking advantage of the fact that the return type might be a specialization
//of the type implementing the operator
public static T operator ++(Person<T> p)
{
return new T { Age = p.Age + 1 };
}
}

class Agent : Person<Agent> { }

//Only required if Person should be usable on it's own
class Person : Person<Person> { }

上面的运算符构造了一个新对象,对我来说它与 ++ 运算符的约定内联,但还需要一个默认构造函数,如果您希望可以使用强制转换来代替它。

public static T operator ++(Person<T> p)
{
p.Age++;
return (T)p;
}

运算符是否被继承取决于您如何定义继承。

C# 规范以不同于 CLI specifications 的方式使用“继承” . C# 规范使用继承的方式是在与 CLI 规范不兼容的运算符和静态方法的上下文中(即 C# 规范与 CLI 规范相矛盾,因此运行 C# 的平台不支持该规范)

要说明为什么我的钱花在“不继承运算符”上,是因为它们是静态方法的语法糖。

[SpecialName]
public static T op_increment(Person<T> p)
{
return new T { Age = p.Age + 1 };
}

那是一个静态方法的实现。根据 CLI 规范,静态方法不会被继承:

A derived object type inherits all of the instance and virtual methods of its base object type. It does not inherit constructors or static methods.

下面是++操作符的实现

public static T operator ++(Person<T> p)
{
return new T { Age = p.Age + 1 };
}

这两个实现的 IL 相同

关于C# 自定义一元运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19724782/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com