产品展示类网站,wordpress如何上传附件,国家企业网,吴江住房城乡建设局网站14.3.2 特定类约束
如果您的泛型类需要使用某个特定子集的类#xff08;特定层次结构#xff09;#xff0c;则可能需要根据给定基类指定约束。
例如#xff0c;如果您声明#xff1a;
typeTCompClassT: TComponent class 则此泛型类的实例仅适用于组…14.3.2 特定类约束
如果您的泛型类需要使用某个特定子集的类特定层次结构则可能需要根据给定基类指定约束。
例如如果您声明
typeTCompClassT: TComponent class 则此泛型类的实例仅适用于组件类即任何TComponent后代类。这使您拥有一个非常特定的泛型类型是的听起来很奇怪但这确实是它的实际情况并且编译器将允许您在处理泛型类型时使用TComponent类的所有方法。
如果这看起来非常强大那么请三思。如果你考虑一下利用继承和类型兼容规则可以实现的功能也许你可以使用传统的面向对象技术来解决同样的问题而不必使用泛型类。我并不是说特定的类约束从来都没有用但它肯定没有更高级别的类约束或我觉得非常有趣的基于接口的约束强大。
14.3.3 接口约束
一般来说更灵活的做法是只接受实现特定接口的类作为类型参数而不是将一个泛型类约束为一个给定的类。这样就可以在泛型的实例上调用接口。在 C# 语言中将接口约束用于泛型也很常见。让我先展示给你一个示例来自IntfConstraint示例。首先我们需要声明一个接口
typeIGetValue interface[{60700EC4-2CDA-4CD1-A1A2-07973D9D2444}]function GetValue: Integer;procedure SetValue(Value: Integer);property Value: Integer read GetValue write SetValue;end; 接下来我们可以定义一个实现它的类
typeTGetValue class(TNoRefCountObject, IGetValue)privateFValue: Integer;publicconstructor Create(Value: Integer 0);function GetValue: Integer;procedure SetValue(Value: Integer);end; 在限制为实现特定接口的类型的泛型类的定义中事情开始变得有趣
typeTInftClassT: IGetValue classprivateFVal1, FVal2: T; // Or IGetValuepublicprocedure Set1(Val: T);procedure Set2(Val: T);function GetMin: Integer;function GetAverage: Integer;procedure IncreaseByTen;end; 请注意在这个类的泛型方法的代码中我们可以编写
function TInftClassT.GetMin: Integer;
beginResult : Min(FVal1.GetValue, FVal2.GetValue);
end;procedure TInftClassT.IncreaseByTen;
beginFVal1.SetValue(FVal1.GetValue 10);FVal2.Value : FVal2.Value 10;
end; 有了所有这些定义我们现在可以按以下方式使用泛型类
procedure TFormIntfConstraint.BtnValueClick(Sender: TObject);
varIClass: TInftClassTGetValue;
beginIClass : TInftClassTGetValue.Create;tryIClass.Set1(TGetValue.Create(5));IClass.Set2(TGetValue.Create(25));Show(Average: IntToStr(IClass.GetAverage));IClass.IncreaseByTen;Show(Min: IntToStr(IClass.GetMin));finallyIClass.FVal1.Free;IClass.FVal2.Free;IClass.Free;end;
end; 为了展示这个泛型类的灵活性我为接口创建了另一个完全不同的实现方法
type
TButtonValue class(TButton, IGetValue)
publicfunction GetValue: Integer;procedure SetValue(Value: Integer);class function MakeTButtonValue(Owner: TComponent; Parent: TWinControl): TButtonValue;
end;function TButtonValue.GetValue: Integer;
beginResult : Left; // use base class property
end;procedure TButtonValue.SetValue(Value: Integer);
beginLeft : Value; // use base class property
end; 该类函数此处未显示在父控件中创建了一个随机位置的按钮。位置创建一个按钮并在以下示例代码中使用
procedure TFormIntfConstraint.BtnValueButtonClick(Sender: TObject);
varIClass: TInftClassTButtonValue;
beginIClass : TInftClassTButtonValue.Create;tryIClass.Set1(TButtonValue.MakeTButtonValue(Self, ScrollBox1));IClass.Set2(TButtonValue.MakeTButtonValue(Self, ScrollBox1));Show(Average: IntToStr(IClass.GetAverage));Show(Min: IntToStr(IClass.GetMin));IClass.IncreaseByTen;Show(New Average: IntToStr(IClass.GetAverage));finallyIClass.Free;end;
end;