2014-09-29 4 views
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#?] (Http://stackoverflow.com/questions/295104/what-is-the-difference-between -a-поле-и-свойство-в-с). –

+1

Используйте ленивую инициализацию или прокси-шаблон. –

ответ

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'. –

+1

@ScottChamberlain Я редактирую, чтобы использовать свойства. Но если бы мне пришлось выбрать один из этих двух, чтобы исправить, я бы выбрал использование типов с плавающей точкой. Свойства порождают более легкое обслуживание; фиксированная точка для получения денежных данных * не делает плохих расчетов *. – cdhowie

2

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

Выполнение расчетов по объектам get.

NB: Что вы общественные поля, а не свойство

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

См this fiddle

например

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 ' заботится о защелке для вас. – cdhowie

+0

Да ... но не все используют .Net 4.x. 'Lazy ' также немного более кратким. –

Смежные вопросы