2016-09-13 1 views
2

Je souhaite être capable de créer une erreur/un avertissement du compilateur si une certaine propriété de mon objet n'est pas définie. Disons que j'ai la classe suivante:Générer une erreur de compilation si la propriété n'est pas définie

interface 

type 
    TBarkevent = procedure (Bark : String) of object; 

    TDog = class 
    private 
    FOnBark : TBarkevent; 
    procedure SetBark(const Value: TBarkevent); 
    function GetBark: TBarkEvent; 
    public 
    procedure Bark; 
    property OnBark : TBarkEvent read GetBark write SetBark; 
    constructor Create; 
    end; 

implementation 

{ TDog } 

procedure TDog.Bark; 
begin 
    if Assigned(OnBark) then 
    OnBark('Woof!') 
end; 

constructor TDog.Create; 
begin 
end; 

function TDog.GetBark: TBarkEvent; 
begin 
    Result := FOnBark; 
end; 

procedure TDog.SetBark(const Value: TBarkevent); 
begin 
    FOnBark := Value; 
end; 

-je utiliser la classe TDog dans une autre unité comme celui-ci:

var 
    Dog : TDog; 
begin 
    Dog := TDog.Create; 
    Dog.OnBark := DogBark; 
    Dog.Bark; 

Maintenant, une fois la procédure Bark() est appelée, l'événement OnBark est déclenché.

Ma question:

moi Est-il possible pour le rendre obligatoire pour spécifier la propriété OnBark, de sorte qu'une erreur du compilateur/avertissement est émis si l'événement est pas défini?

+0

Parfois, vous devez monter à la plaque et faire les choses correctement. Le compilateur ne peut pas faire votre travail pour vous. –

+0

@DavidHeffernan Le problème est que, d'ici quelques années, quelqu'un d'autre que moi pourrait finir par utiliser ce code et avoir quelque chose qui leur dit qu'ils ont fait une erreur au début pourrait économiser beaucoup de temps et d'efforts –

+1

Cela s'appelle la documentation –

Répondre

5

Définissez votre classe:

TDog = class 
private 
    FOnBark : TBarkevent; 
    procedure SetBark(const Value: TBarkevent); 
    function GetBark: TBarkEvent; 
public 
    procedure Bark; 
    property OnBark : TBarkEvent read GetBark write SetBark; 
    constructor Create(Bark : TBarkEvent); 
end; 

De cette façon, vous ne pouvez pas instancier un objet TDog sans spécifier un événement. Si vous essayez, vous obtiendrez une erreur de compilation.

+1

Vrai, cependant l'événement pourrait toujours recevoir une valeur' nil', ce qui ne satisfait pas les exigences de l'OP. –

+0

D'accord avec @RemyLebeau, mais il est possible de vérifier zéro dans le constructeur et lever et exception dans ce cas –

+1

@RemyLebeau: Pourquoi pas? L'affectation d'une valeur NIL continue d'affecter une valeur. Il y a même une vérification dans la méthode Bark quant à savoir si la valeur est non-NIL, donc il est évident (pour moi) qu'une valeur NIL est une valeur valide. Si ce n'est pas le cas, la méthode Bark devrait simplement appeler l'événement FOnBark et le laisser tomber si une valeur non NIL n'est pas affectée. Si NIL n'est pas une valeur valide, une vérification dans CONSTRUCTOR doit être implémentée et la vérification dans la méthode Bark doit être supprimée. – HeartWare

1

Tout d'abord: Non Il n'est pas possible de vérifier cela lors de la compilation pour une propriété comme celle-ci.

Pour le rendre presque obligatoire pour mettre en œuvre un événement OnBark, vous pouvez l'ajouter en tant que paramètre constructeur, au lieu de le publier comme une lecture/écriture propriété. Ensuite, vous pouvez utiliser Assert() pour le vérifier au moment de l'exécution, lors de l'appel du constructeur si une méthode de rappel valide a été transmise au constructeur.

Pour rendre vraiment obligatoire, vous pouvez déclarer ce qui suit:

TCustomDog = class 
public 
    procedure Bark; virtual; abstract; 
end; 

Ainsi, tout le monde en utilisant TCustomDog classe doit mettre en œuvre la procédure Bark. S'il ne le fait pas, un avertissement du compilateur sera émis.

+0

Juste pour clarifier: la manière CONSTRUCTOR générerait une erreur. La méthode ABSTRACT ne générerait (par défaut) qu'un avertissement ...Ainsi (IMO) la façon CONSTRUCTOR serait le meilleur choix. – HeartWare

+1

Comment la méthode abstraite rend-elle obligatoire OnBark? – kobik

+0

@kobik: ce n'est pas le cas. Le code devrait dériver une autre classe de 'TCustomDog' et surcharger' Bark() 'avec une implémentation concrète au lieu d'utiliser un événement. –