Указатели на типизированную переменную в C #: интерфейс, универсальный объект, объект или класс?(Бокс / распаковка) - PullRequest
0 голосов
/ 06 января 2011

Прежде всего, я прошу прощения, если об этом спрашивали тысячу раз. Я прочитал свою книгу по C #, я погуглил ее, но, похоже, я не могу найти ответ, который ищу, или я упускаю момент очень долго.

Я очень смущен всей проблемой бокса / распаковки. Скажем, у меня есть поля разных классов, все возвращающие типизированные переменные (например, 'double'), и я хотел бы, чтобы переменная указывала на любое из этих полей. В простом старом C я бы сделал что-то вроде:

double * newVar;
newVar = &oldVar;
newVar = &anotherVar;
...

У меня таймер вызывает функцию и передает значение указанной ссылки:

ChartPlotData(*newVar);

Причина, по которой я ищу указатель, заключается в том, что newVar изменяется во время выполнения, связанное с событием:

public void checkbox_Clicked(object sender ...)
  if (sender == checkbox1) value = &object1.field1;
  if (sender == checkbox2) value = &object2.field1;

Как это можно сделать в C #?

EDIT1: Объясненная цель ссылки.

РЕДАКТИРОВАТЬ2: сделал несколько неправильных заявлений, удалил их и сократил вопрос.

Ответы [ 4 ]

1 голос
/ 06 января 2011

У вас может быть событие щелчка, как предложено в вашем редактировании, и затем использовать делегата для выбора данных, которые будут переданы в элемент управления.Я не уверен, что это будет соответствовать вашим требованиям к производительности.

ChartPlotData(valueSelector());

// ...

Func<double> valueSelector;

protected void Checkbox_Click(object sender /* ... */)
{
    if (sender == checkbox1) valueSelector = () => object1.field1;
    if (sender == checkbox2) valueSelector = () => object2.field1;
    // ...
}

(Если вы предпочитаете и можете, вы можете перегрузить свой ChartPlotData метод, чтобы принять Func<double> вместо простого double, а затем лениво вызывать делегат селектора внутри метода, а не на сайте вызова.)

0 голосов
/ 06 января 2011

Вы можете обратиться к существующему типу значения, используя ключевое слово ref .

public static void ModifyNumber(ref int i)
{
    i += 1;
}

static void Main(string[] args)
{
    int num = 4;
    ModifyNumber(ref num);
    ModifyNumber(ref num);
    ModifyNumber(ref num);
    ModifyNumber(ref num);


    // num now equals 8


}
0 голосов
/ 06 января 2011

Я не уверен, зачем вам нужен адрес переменной.Двойной тип значения и хранится в стеке.Чтобы передать его методом в ссылку, просто используйте ключевое слово C # ref.Из упомянутых вами случаев я лично предпочел бы что-то вроде этого:

class Program
{
    public class Refferenced<T> where T : struct 
    {
        public T Value { get; set; }
    }

    static void Main(string[] args)
    {
        Refferenced<double> x = new Refferenced<double>();
        Refferenced<double> y = new Refferenced<double>();
        y.Value = 2;
        x = y;
        x.Value = 5;
        Console.WriteLine(x.Value);
        Console.WriteLine(y.Value);
        y.Value = 7;
        Console.WriteLine(x.Value);
        Console.WriteLine(y.Value);

        Console.ReadKey();
    }

Это похоже на типы C # NullAble.

0 голосов
/ 06 января 2011

Простые типы и структуры имеют тип значения в C #. Вы ничего не можете с этим поделать, если только вы не упомянули, что используете небезопасный модификатор. Сказав это, ваши возможности ограничены.

  1. Использовать объект вместо примитивных типов.
  2. Используйте массивы размером 1.
  3. Пользовательский универсальный прокси-класс, инкапсулирующий любой из вышеперечисленных.
  4. ???
...