Когда возвращается экземпляр класса, возвращаются ли все свойства?

1

Скажем, у меня есть класс Customer с некоторыми свойствами:

public class Customer
{
    public string CustAddr = GetCustAddr(); //Long procedure returning address

    public double CustAcct = GetCustAcct(); //Long procedure returning account

    public string CustInvoice = GetCustInvoice(); //Long procedure returning invoice
}

Этот класс возвращается через функцию:

public Customer GetData(string query)
{
    Customer cust = new Customer();
    //set the values for each of the properties
    return cust;
}

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

lblDisplay = GetData("QUERY").CustAddr.ToString();

Однако предположим, что каждому свойству требуется много времени для вычисления. Если мне нужно только значение CustAddr, оно все равно вычисляется и доступно для CustAcct и CustInvoice.

Как мне изменить свою функцию, чтобы вернуть только свойство, которое я ищу, кроме того, чтобы разбить мой класс на отдельные процедуры для вызова? Например, я мог бы просто:

lblDisplay = GetCustAddr().ToString();

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

  • 4
    Это поля, а не свойства;)
  • 2
    Я предлагаю прочитать В чем разница между полем и свойством в C #? ,
Показать ещё 1 комментарий
Теги:
class
winforms

3 ответа

5
Лучший ответ

Это отличный кандидат на ленивую инициализацию. Здесь я представляю пример использования свойств (у вас есть поля).

public class Customer
{
    public Lazy<string> CustAddr { get; private set; }
    public Lazy<double> CustAcct { get; private set; }
    public Lazy<string> CustInvoice { get; private set; }

    public Customer()
    {
        CustAddr = new Lazy<string>(GetCustAddr);
        CustAcct = new Lazy<double>(GetCustAcct);
        CustInvoice = new Lazy<string>(GetCustInvoice);
    }
}

Однако я бы отказался, если бы не указал, что вам не следует использовать типы с плавающей точкой (float, double) для хранения денежных значений. Вместо этого используйте decimal.

  • 0
    Вы указываете на использование double вместо decimal но вы не упоминаете тот факт, что он выставляет открытые поля, а не свойства?
  • 3
    Тем не менее, неясно, почему OP не сохраняет объект в переменной и не обращается к каждому свойству по одному, а не всегда создает его через GetData .
Показать ещё 3 комментария
2

Зачем использовать экзотическое решение, когда есть ванильный?

Реализация расчета на get свойств.

NB: у вас есть публичные поля, а не свойства

Очень простое решение (ничего экзотического!)

Смотрите эту скрипку

например

public class Customer
{
    private double ? _custAcct = null;
    public double CustAcct
    {
        get
        {
            if (!_custAcct.HasValue)
            {
                _custAcct = GetCustAcct();
            }

            return _custAcct.Value;
        }
    }

    private double GetCustAcct()
    {
        // do something that takes a long time
        return 1234.45;
    }
}
1

То, о чем вы говорите, это ленивая загрузка или ленивая инициализация. Вы пишете свои свойства примерно так:

public class MyLazyWidget
{
  . . .
  public BigExpensiveObject MyLazyProperty
  {
    get
    {
      if ( BigExpensiveObjectBackingStore == null )
      {
        BigExpensiveObjectBackingStore = ExpensiveOperation() ;
      }
        return BigExpensiveObjectBackingStore ;
    }
  }
  private static BigExpensiveObjectBackingStore = null ;
  . . .
}

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

public class MyLazyWidget
{
  . . .
  public BigExpensiveObject MyLazyProperty
  {
    get
    {
      lock( MyLazyPropertyLatch )
      {
        if ( BigExpensiveObjectBackingStore == null )
        {
          BigExpensiveObjectBackingStore = ExpensiveOperation() ;
        }
      }
      return BigExpensiveObjectBackingStore ;
    }
  }
  private static readonly object MyLazyPropertyLatch = new object() ;
  private static BigExpensiveObjectBackingStore = null ;
  . . .
}
  • 0
    Обратите внимание, что Lazy<T> позаботится о защелке для вас.
  • 0
    Да ... но не все используют .Net 4.x. Lazy<T> также немного лаконичнее.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню