Что такое хорошее использование для помощников класса?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
36
задан menjaraz 26 December 2011 в 12:02
поделиться

8 ответов

Я использую их:

  • К вставляют перечислители в классы VCL, которые не реализуют их.
  • К улучшают классы VCL.
  • Для добавления методов к классу TStrings, таким образом, я могу использовать те же методы в мои полученные списки и в TStringList.

    TGpStringListHelper = class helper for TStringList
    public
      function  Last: string;
      function  Contains(const s: string): boolean;
      function  FetchObject(const s: string): TObject;
      procedure Sort;
      procedure Remove(const s: string);
    end; { TGpStringListHelper }
    
  • Для упрощения доступа для записи полей и удаляют кастинг .

33
ответ дан gabr 27 November 2019 в 05:52
поделиться

Это очень походит на дополнительные методы в C#3 (и VB9). Лучшее использование я видел их, является расширениями IEnumerable<T>IQueryable<T>), который позволяет LINQ работать против произвольных последовательностей:

var query = someOriginalSequence.Where(person => person.Age > 18)
                                .OrderBy(person => person.Name)
                                .Select(person => person.Job);

(или что бы то ни было, конечно). Все это выполнимо, потому что дополнительные методы позволяют, Вы к эффективно цепочечному вместе звоните в статические методы, которые берут тот же тип, как они возвращаются.

6
ответ дан Jon Skeet 27 November 2019 в 05:52
поделиться

Сначала я был видом скептика о помощниках класса. Но тогда я считал интересное запись в блоге , и теперь я убежден, что они действительно полезны.

, Например, если Вы хотите дополнительную функциональность для существующего класса экземпляра и по некоторым причинам Вы не в состоянии изменить существующий источник. Можно создать помощника класса для добавления этой функциональности.

Пример:

type
  TStringsHelper = class helper for TStrings
  public
    function IsEmpty: Boolean;
  end;

function TStringsHelper.IsEmpty: Boolean;
begin
  Result := Count = 0;
end;

Каждый раз, мы теперь используем экземпляр (подкласс) TStrings, и TStringsHelper в объеме. У нас есть доступ к методу IsEmpty.

Пример:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Memo1.Lines.IsEmpty then
    Button1.Caption := 'Empty'
  else
    Button1.Caption := 'Filled';
end;

Примечания:

  • помощники Класса могут быть сохранены в отдельной единице, таким образом, можно добавить собственных изящных помощников класса. Обязательно дайте этим единицам легкое для запоминания имени как ClassesHelpers для помощников для единицы Классов.
  • существуют также рекордные помощники.
  • , Если существует несколько помощников класса в объеме, ожидайте некоторые проблемы, только один помощник может использоваться.
14
ответ дан Toon Krijthe 27 November 2019 в 05:52
поделиться

Они очень полезны для плагинов. Например, скажем, Ваш проект определяет определенную структуру данных, и он сохраняется на диск определенным способом. Но тогда некоторая другая программа делает что-то очень похожее, но отличающийся файл данных. Но Вы не хотите чрезмерно увеличивать размер своего EXE с набором кода импорта для функции, которую не должно будет использовать много Ваших пользователей. Можно использовать сменную платформу и поместить средства импорта в плагин, который работал бы как это:

type
   TCompetitionToMyClass = class helper for TMyClass
   public
      constructor Convert(base: TCompetition);
   end;

И затем определяют преобразователь. Один протест: помощник класса не является другом класса . Эта техника будет только работать, если будет возможно полностью установить новый объект TMyClass через свои открытые методы и свойства. Но если Вы можете, это работать действительно хорошо.

4
ответ дан Mason Wheeler 27 November 2019 в 05:52
поделиться

В первый раз я не забываю испытывать то, что Вы звоните "помощникам класса", был при изучении Objective C. Какао (платформа Objective C Apple) использует то, что называют "Категориями".

категория А позволяет Вам расширять существующий класс путем добавления, что Вы владеете методами без разделения на подклассы. На самом деле Какао поощряет Вас стараться не разделять на подклассы, если это возможно. Часто имеет смысл разделять на подклассы, но часто это могут быть избегавшие использования категории.

А хороший пример использования категории в Какао - то, что называют "Кодом значения ключа (KVC)" и "Наблюдением значения ключа (KVO)".

Эта система реализована с помощью двух категорий (NSKeyValueCoding и NSKeyValueObserving). Эти категории определяют и реализуют методы, которые могут быть добавлены к любому классу, который Вы хотите. Например, Какао добавляет "соответствие" к KVC/KVO при помощи этих категорий для добавления методов к NSArray, таких как:

- (id)valueForKey:(NSString *)key

класс NSArray не имеет ни одного объявлением, ни реализацией этого метода. Однако посредством использования категории. Можно назвать тот метод на любом классе NSArray. Вы не обязаны разделять NSArray на подклассы для получения соответствия KVC/KVO.

NSArray *myArray = [NSArray array]; // Make a new empty array
id myValue = [myArray valueForKey:@"name"]; // Call a method defined in the category

Используя эту технику облегчает добавлять поддержку KVC/KVO Вашим собственным классам. Интерфейсы Java позволяют Вам добавлять объявления метода, но категории позволяют Вам также добавлять фактическую реализацию к существующим классам.

3
ответ дан Robert Walker 27 November 2019 в 05:52
поделиться

Поскольку GameCat показывает, TStrings является хорошим кандидатом для предотвращения некоторого ввода:

type
  TMyObject = class
  public
    procedure DoSomething;
  end;

  TMyObjectStringsHelper = class helper for TStrings
  private
    function GetMyObject(const Name: string): TMyObject;
    procedure SetMyObject(const Name: string; const Value: TMyObject);
  public
    property MyObject[const Name: string]: TMyObject read GetMyObject write SetMyObject; default;
  end;

function TMyObjectStringsHelper.GetMyObject(const Name: string): TMyObject;
var
  idx: Integer;
begin
  idx := IndexOf(Name);
  if idx < 0 then
    result := nil
  else
    result := Objects[idx] as TMyObject;
end;

procedure TMyObjectStringsHelper.SetMyObject(const Name: string; const Value:
    TMyObject);
var
  idx: Integer;
begin
  idx := IndexOf(Name);
  if idx < 0 then
    AddObject(Name, Value)
  else
    Objects[idx] := Value;
end;

var
  lst: TStrings;
begin
  ...
  lst['MyName'] := TMyObject.Create; 
  ...
  lst['MyName'].DoSomething;
  ...
end;
<час>

необходимо ли было когда-либо получать доступ ко много строкам строки в реестре?

type
  TRegistryHelper = class helper for TRegistry
  public
    function ReadStrings(const ValueName: string): TStringDynArray;
  end;

function TRegistryHelper.ReadStrings(const ValueName: string): TStringDynArray;
var
  DataType: DWord;
  DataSize: DWord;
  Buf: PChar;
  P: PChar;
  Len: Integer;
  I: Integer;
begin
  result := nil;
  if RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, nil, @DataSize) = ERROR_SUCCESS then begin
    if DataType = REG_MULTI_SZ then begin
      GetMem(Buf, DataSize + 2);
      try
        if RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, PByte(Buf), @DataSize) = ERROR_SUCCESS then begin
          for I := 0 to 1 do begin
            if Buf[DataSize - 2] <> #0 then begin
              Buf[DataSize] := #0;
              Inc(DataSize);
            end;
          end;

          Len := 0;
          for I := 0 to DataSize - 1 do
            if Buf[I] = #0 then
              Inc(Len);
          Dec(Len);
          if Len > 0 then begin
            SetLength(result, Len);
            P := Buf;
            for I := 0 to Len - 1 do begin
              result[I] := StrPas(P);
              Inc(P, Length(P) + 1);
            end;
          end;
        end;
      finally
        FreeMem(Buf, DataSize);
      end;
    end;
  end;
end;
3
ответ дан Uwe Raabe 27 November 2019 в 05:52
поделиться

Я видел их используемый для предоставления доступа методы класса, последовательные через классы: Открытое/Близкое Добавление и Показывает/Скрывает всем классам данного "типа", а не только Активных и Свойств видимости.

0
ответ дан Jamo 27 November 2019 в 05:52
поделиться

I would not recommend to use them, since I read this comment:

"The biggest problem with class помощники, от первого лица их использования в ваших собственных приложениях, это факт что только ОДИН помощник класса для данного class может быть в области видимости в любое время ". ... "То есть, если у вас есть два помощника по объему будет признан только ОДИН компилятором. Вы не получите ничего предупреждения или даже намеки на любые другие помощники, которые могут быть скрыты ".

http://davidglassborow.blogspot.com/2006/05/class-helpers-good-or-bad.html

2
ответ дан 27 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: