c # body setter body, не оголошуючи змінну властивості класу

Чи потрібно мені оголосити змінну класу для збереження властивості, чи я можу просто послатися на self. {Propertyname} в getter/setter?

Іншими словами, чи можу я зробити це? (де я не визначив mongoFormId де завгодно):

public string mongoFormId 
{
    get
    {
        return this.mongoFormId;
    }
    set
    {
        this.mongoFormId = value;
        revalidateTransformation();
    }
}
8
Ви отримаєте стековий потік з цим кодом :)
додано Автор NibblyPig, джерело
+1 StackOverflowException
додано Автор meorfi, джерело
Залежить, де код, який ти написав, йде?
додано Автор Mike, джерело

8 Відповіді

Ви можете використовувати автоматичні підключення або для реалізації власних. Якщо ви використовуєте автоматичні підключення, C# компілятор створить для вас поле для резервної копії, але якщо ви реалізуєте свої власні, ви повинні вручну надавати поле для резервної копії (або обробляти значення іншим способом).

private string _mongoFormId;

public string mongoFormId 
{
    get { return this._mongoFormId; }
    set 
    {
        this._mongoFormId = value;
        revalidateTransformation();
    }
}

UPDATE: Since this question was asked, C# 6.0 has been released. However, even with the new syntax options, there is still no way to provide a custom setter body without the need to explicitly declare a backing field.

12
додано

Вам потрібно встановити змінну поля та зберегти значення там, якщо ви збираєтеся використовувати власний геттер і сеттер.

За допомогою коду, який ви зараз маєте, ви будете працювати в винятці надлишку стека. Коли ви призначите щось для mongoFormId , ви виконаєте рядок this.MongoFormId = value; . Це завдання до mongoFormId , в результаті чого виконується рядок this.MongoFormId = value; і так далі. Це ніколи не зупиниться.

Правильним способом є поле:

    private string _mongoFormId;
    public string mongoFormId {
        get { return this._mongoFormId; }
        set {
            this._mongoFormId = value;
            revalidateTransformation();
        }
    }
3
додано

Ви повинні мати змінну backing. Уважніше:

get { return this.mongoFormId; }

Ви отримаєте назву getter на mongoFormId , який буде викликати цей код знову, і знову, і знову! Визначення основної змінної дозволить уникнути нескінченного рекурсивного дзвінка.

2
додано
public string mongoFormId {
    get {
        return this.mongoFormId;
    }
    set {
        this.mongoFormId = value;
        revalidateTransformation();
    }
}

таким чином у вас є рекурсивна функція на всіх шляхах Єдиний спосіб, який я бачу, це використання приватного члена даних. Як розповідає інші хлопці.

0
додано

Check MSDN Properties Overview

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

0
додано

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

Так, так, вам потрібно оголосити приватне поле. І щоб уникнути плутанини, створіть властивості, слідуючи MSDN Naming Посібник (Використовуйте приклади Pascal для властивостей, справа для верблюдів для приватних полів). І будь-ласка, будь-ласка, використовуйте те ж саме для ваших методів, замість revalidateTransformation слід використовувати RevalidateTransformation , якщо ви виконаєте конвенцію C#, а не Java.

private string mongoFormId;
public string MongoFormId 
{
    get 
    { 
        return mongoFormId; 
    }
    set 
    {
        mongoFormId = value;
        RevalidateTransformation();
    }
}
0
додано

Це не спрацює, оскільки ви отримаєте рекурсивний виклик у власність. Якщо я не помиляюся, результат буде StackOverflowException . Ви повинні використовувати змінну.

    private string mongoFormId;
    public string MongoFormId 
    {
        get
        {
            return this.mongoFormId;
        }
        set
        {
            this.mongoFormId = value;
            revalidateTransformation();
        }
    }

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

public string MongoFormId { get; set; }
0
додано

Ви можете зробити це обидва способи.

If you want to have a class level member variable then do it this way -

public class sampleClass
{
     private string _mongoFormId;

public string mongoFormId {
            get { return _mongoFormId; }
            set {
                _mongoFormId = value;
                revalidateTransformation();
            }
        }
}

Або зробити це простим у класі, якщо немає необхідності повторного виклику виконання перетворення() там

public class sampleClass
{
public string mongoFormId {get; set;}
}
0
додано
переконайтеся, що він хоче викликати revalidateTransformation (); в setter. Ви можете отримати "-" без уваги
додано Автор meorfi, джерело
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug