Передача властивості як параметра 'out' у C #


81

Припустимо, у мене є:

public class Bob
{
    public int Value { get; set; }
}

Я хочу передати члена Value як вихідний параметр типу

Int32.TryParse("123", out bob.Value);

але я отримую помилку компіляції, аргумент "out" не класифікується як змінна. " Чи є спосіб досягти цього, або мені доведеться витягти змінну, а-ля:

int value;
Int32.TryParse("123", out value);
bob.Value = value;

Відповіді:


83

Вам доведеться явно використовувати властивість field і "normal" замість автоматично реалізованої властивості:

public class Bob
{
    private int value;
    public int Value
    { 
        get { return value; } 
        set { this.value = value; }
    }
}

Тоді ви можете передати поле як параметр out:

Int32.TryParse("123", out bob.value);

Але, звичайно, це буде працювати лише в тому ж класі, оскільки поле є приватним (і повинно бути!).

Властивості просто не дозволяють вам цього робити. Навіть у VB, де ви можете передавати властивість за посиланням або використовувати його як вихідний параметр, в основному є додаткова тимчасова змінна.

Якщо вас не хвилювало повернене значення TryParse, ви завжди можете написати свій власний допоміжний метод:

static int ParseOrDefault(string text)
{
    int tmp;
    int.TryParse(text, out tmp);
    return tmp;
}

Потім використовуйте:

bob.Value = Int32Helper.ParseOrDefault("123");

Таким чином, ви можете використовувати одну тимчасову змінну, навіть якщо вам потрібно це зробити в кількох місцях.


1
Я думаю, що проблема з першим підходом полягає в тому, що якщо ви використовуєте поле безпосередньо (замість властивості), ви можете обійти правила перевірки, які можуть існувати у властивості
Андреас Грех, 02

3
@Jon: Я думаю, ви хотіли б змінити int.Parse на int.TryParse у прикладі ParseOrDefault.
shahkalpesh 02

8
До речі, причина, по якій ви не можете мати властивість як вихідний параметр, полягає в тому, що встановлення властивості насправді є викликом функції і не призначається, якщо ви дивитесь під капот.
Dirk Vollmar

3
Я хотів би бачити правильний синтаксичний цукор, щоб дозволити мені передавати властивість як параметр ref або out. Давайте виконаємо роботу з компілятором, це швидше, ніж я.
Ігнасіо Солер Гарсія

1
@SoMoS: Незалежно від того, чи це тип цінності, чи ні, це не має значення для мого коментаря. Або зміна параметра в методі параметра негайно набуває чинності, або це не відбувається. Це впливає на те, що трапляється, якщо також буде створено виняток.
Джон Скіт,

7

Ви можете досягти цього, але не завдяки властивості.

public class Bob {
    public int Value { get; set; } // This is a property

    public int AnotherValue; // This is a field
}

Ви не можете використовувати outна Value, але ви можете на AnotherValue.

Це спрацює

Int32.TryParse("123", out bob.AnotherValue);

Але загальноприйняті вказівки говорять вам, що ви не повинні публікувати заняття. Тому слід використовувати підхід тимчасової змінної.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.