В C ++ вы могли бы написать следующий код:
int Animal::*pAge= &Animal::age;
Animal a;
a.*pAge = 50;
Есть ли подобная функциональность в C #?
Редактировать: Чтобы уточнить, я не спрашивать об указателях.Я спрашиваю об «указателях на членов», функция, найденная в C ++, которая используется с операторами .*
и ->*
.
Edit 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 # похожую функциональность?