c# - C# 是否有指向 C++ 中的成员的指针?
问题描述
在 C++ 中,您可以编写以下代码:
int Animal::*pAge= &Animal::age;
Animal a;
a.*pAge = 50;
C#中是否有类似的功能?
编辑:为了澄清,我不是在问指针。我问的是“指向成员的指针”,这是 C++ 中与.*
and->*
运算符一起使用的一个特性。
编辑 2:这是成员指向指针的用例示例。
假设我们有以下类:
class Animal
{
int age;
int height;
int weight;
…
}
假设我们要编写可以找到平均年龄/身高/体重/等的方法。数组中的所有动物。然后我们可以这样做:
int averageAge(Animal[] animals)
{
double average = 0;
for (…)
average += animals[i].age;
return average/animals.length;
}
int averageHeight(Animal[] animals)
{
//code here again
}
int averageWeight(Animal[] animals)
{
//code here again
}
我们最终会在这里复制和粘贴大量代码,如果我们查找平均值的算法发生变化,我们将遇到维护噩梦。因此,我们想要对任何成员的这个过程进行抽象。考虑这样的事情:
int averageAttribute(Animal[] animals, Func<Animal, int> getter)
{
double average = 0;
for (…)
average += getter(animals[i]);
return average/animals.length;
}
然后我们可以调用
averageAttribute(animals, (animal) => animal.age);
或类似的东西。然而,使用委托比它必须的要慢;我们使用整个函数只是为了返回结构中某个位置的值Animal
。在 C++ 中,指向指针的成员允许您对结构进行指针数学运算(不是正确的术语,但我想不出更好的术语)。正如你可以说的
int p_fourthAnimal = 3;
(animals + p_fourthAnimal)*
要在存储在变量中的指针之前获取这么多字节的值animals
,在 C++ 中,您可以说
int Animal::* p_age = &Animal::age;
animal.*p_age //(animal + [the appropriate offset])*
在存储在变量中的指针之前获取这么多字节的值animal
;从概念上讲,编译器将animal.*p_age
变成(animal + [the appropriate offset])*
. 因此,我们可以将我们averageAttribute
的声明为:
int averageAttribute(Animal[] animals, Animal::* member)
{
double average = 0;
for (…)
average += animals[i].*member; //(animals[i] + [offset])*
return average/animals.length;
}
然后我们可以调用
averageAttribute(animals, &Animal::age);
总之,指向成员的指针允许您将诸如我们的方法抽象averageAttribute
到结构的所有成员,而无需复制和粘贴代码。虽然委托可以实现相同的功能,但如果您知道实际上不需要函数分配给您的自由,那么获取结构成员的效率相当低,甚至可能存在边缘用例,其中委托是不够的,但我无法给出此类用例的任何示例。C# 有类似的功能吗?
解决方案
正如其他人在这里评论的那样,委托是在 C# 中实现此目的的方法。
虽然委托可以实现相同的功能,但如果您知道您实际上并不需要函数分配给您的自由,那么获取结构成员的效率相当低
这取决于编译器和运行时如何实现该委托。他们很可能会看到这是一个微不足道的函数,并优化了调用,就像他们对微不足道的 getter 和 setter 所做的那样。例如,在 F# 中,您可以实现:
type Animal = { Age : int }
let getAge (animal:Animal) =
animal.Age
let inline average (prop:Animal->int) (animals:Animal[]) =
let mutable avg = 0.
for animal in animals do
avg <- avg + float(prop(animal)) // no function call in the assembly here when calling averageAge
avg / (float(animals.Length))
let averageAge = average getAge
推荐阅读
- typescript - Vue CLI 3 typescript - 类型“Vue”上不存在属性“x”
- opengl - 如何将一组无绑定图像放入 ubo
- go - 如何将 []byte 转换为 [8]uint8
- ssl - 浏览器多久会自动重置 SSL 缓存?
- css - 如何仅在悬停时显示截断的文本而不更改框列表的高度?
- python - Odoo 11:如何在 javascript 中获取当前记录
- angular - 是否可以更改 angular2-datepicker bigbanner 时间格式?
- vba - If Monday then add x y z
- python - Sankey Diagram Jupyter Notebook
- javascript - jQuery过滤方法中的多个条件