我想知道:如果我创建一个带有私有构造函数的单例类和一个静态方法,它将返回此类的实例并将其置于汇编中,如果我从两个不同的应用程序访问此实例会发生什么?
应用程序是否始终共享单例的相同实例?
如果这两个应用程序都从内存中卸载,那么实例也将被释放?
谢谢.
场景是这样的:
我们有一些SQL表.我们正在对此表执行SQL查询,并且我们在TADOQuery对象中有结果.
var
qryOryginal, qryClone: TADOQuery;
begin
//setup all the things here
qryOryginal.Active := True;
qryClone.Clone(qryOryginal, ltBatchOptimistic);
qryOryginal.Delete; //delete in qryOryginal casues that qryClone deletes its record too!
end;
Run Code Online (Sandbox Code Playgroud)
因此,在克隆DataSet之后,我的qryClone应该保存并且独立数据(至少我是这么认为的).但是,在qryOryginal上执行Delete会导致qryClone上的操作相同.我不希望这样.
有任何想法吗?
我知道我可以将数据存储在TClientDataSet中的其他位置,但我想首先尝试上述解决方案.
在此先感谢您的时间.
在DataSet.Tables[0].Columns[0]我们有一个DataType属性.现在,我想迭代Columns并执行一些操作,具体取决于Typein DataType.这该怎么做?
foreach(var c in DataSet.Tables[0].Columns)
{
if (c.DataType == System.String) {} //error 'string' is a 'type', which is not valid in the given context
}
Run Code Online (Sandbox Code Playgroud) 在使用Debug Build Configuration编译项目时,我有一个想法在FullDebugMode中使用FastMM4.
当我选择Debug构建配置时,Delphi会自动将DEBUG设置为条件定义.所以,这段代码应该按预期工作:
unit uXTrackUpdater;
program Test;
uses
{$IFDEF DEBUG}FastMM4,{$ENDIF}
Forms;
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := 'Test';
Application.CreateForm(TfrmTest, frmMain);
Application.Run;
Run Code Online (Sandbox Code Playgroud)
它有效.但是,当我将构建配置更改为Release配置时.这段代码也有效!它不应该?由于不应定义DEBUG条件.
因此,有人可以解释为什么这个代码执行而不管构建配置如何以及如何正确设置它(以仅在使用调试配置时编译FastMM4的方式).
编辑后
使用FastMM只是一个例子.在发布我的问题之前,我已经在不同的情况下测试了它.这里是:
program Project21;
{$APPTYPE CONSOLE}
uses
{$IFDEF DEBUG} SysUtils; {$ENDIF}
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
except
on E:Exception do //should not be found after rebuilding with RELEASE build configuration
Writeln(E.Classname, ': ', E.Message);
end;
end.
Run Code Online (Sandbox Code Playgroud)
无论构建配置如何,上面的代码都将编译.为什么?
第二次编辑后
我知道,其他人说我的例子按预期工作.但他们不适合我.我在Delphi 2010上检查了这个行为,它是完全相同的(仍然无法正常工作).
也许这会有所帮助:我已经取代了DEBUG指令,RELEASE看看会发生什么.结果是RELEASE …
我正在玩代码文档和实时模板,我很不明白.
我已经阅读了Dr.Bob关于生成有关实时模板的文档和维基文章的文章,但我对类描述有一个问题.
通过类描述我理解当我将鼠标光标指向类声明时的IDE行为.
例如,我有这样的类与它的描述:
type
{$REGION 'TMyClass'}
/// <summary>
/// Summary works
/// </summary>
/// <remarks>
/// Remarks works
/// </remarks>
/// <exception cref="www.some.link">This works</exception>
/// <list type="bullet">
/// <item>
/// <description>description does not work</description>
/// </item>
/// <item>
/// <description>description does not work</description>
/// </item>
/// </list>
/// <permission cref="www.some.link">This works</permission>
/// <example>
/// <code>
/// Code example does not work
/// </code>
/// </example>
{$ENDREGION}
TMyClass = class
private
a, b, c: Integer;
public
end;
Run Code Online (Sandbox Code Playgroud)
后来在代码中我有这样的声明: …
请考虑这样的场景:
我有一个被调用的组件TMenuItemSelector,它有两个已发布的属性:PopupMenu- 允许TPopupMenu从表单中选择一个实例,并MenuItem允许从表单中选择任何实例TMenuItem.
我想以MenuItem一种方式修改属性的属性编辑器,在PopupMenu分配时,只有菜单项PopupMenu才能在下拉列表中看到.
我知道我需要编写自己的后代TComponentProperty和覆盖GetValues方法.问题是我不知道如何访问TMenuItemSelector正在撒谎的表单.
Original TComponentProperty使用此方法迭代所有可用实例:
procedure TComponentProperty.GetValues(Proc: TGetStrProc);
begin
Designer.GetComponentNames(GetTypeData(GetPropType), Proc);
end;
Run Code Online (Sandbox Code Playgroud)
但是,Designer似乎是预编译的,所以我不知道它是如何GetComponentNames工作的.
这就是我到目前为止所做的,我想我唯一缺少的是实现GetValues:
unit uMenuItemSelector;
interface
uses
Classes, Menus, DesignIntf, DesignEditors;
type
TMenuItemSelector = class(TComponent)
private
FPopupMenu: TPopUpMenu;
FMenuItem: TMenuItem;
procedure SetPopupMenu(const Value: TPopUpMenu);
procedure SetMenuItem(const Value: TMenuItem);
published
property PopupMenu: TPopUpMenu read FPopupMenu write SetPopupMenu; …Run Code Online (Sandbox Code Playgroud) 我在使用泛型方面遇到了问题.我不知道如何传递OnCallbackWrapper给CallbackWrapper程序.我在以下示例中遇到"不兼容类型"错误:
unit uTest;
interface
uses
Generics.Defaults;
type
TGenericCallback<T> = procedure(Fields: T);
type
TSpecificFields = record
A: Integer;
B: Integer;
C: Integer;
end;
const
SpecificFields: TSpecificFields =
(A: 5; B: 4; C: 3);
procedure CallbackWrapper(GenericCallback: TGenericCallback<TSpecificFields>);
implementation
procedure CallbackWrapper(GenericCallback: TGenericCallback<TSpecificFields>);
begin
GenericCallback(SpecificFields);
end;
procedure OnCallbackWrapper(const Fields: TSpecificFields);
begin
Assert(Fields.A = 5);
Assert(Fields.B = 4);
Assert(Fields.C = 3);
end;
procedure Dummy;
begin
CallbackWrapper(OnCallbackWrapper); //Incompatible types here
end;
end.
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?谢谢.
背景
最近,我的同事在我们的测试项目中添加了一些新的测试.其中一个没有传递或持续集成系统.由于我们有大约800个测试,并且运行所有这些测试需要一个小时,因此我们经常会犯错误并在我们的开发机器上运行我们当前实施的测试.这种方法有其弱点,因为有时测试是在本地传递但在集成系统上失败.当然,有人可以说"这不是一个错误,测试应该是彼此独立的!".
在理想的世界......当然,但不是在我的世界.不是在你有很多单例初始化的世界里,initializationDelphi本身引入了很多全局变量,在后台初始化了一个OTL线程池,DevExpress方法挂钩你的控件用于绘画目的......还有很多其他的东西我不知道.因此,在最终结果中,一个测试可以改变其他测试的行为.(当然这本身就很糟糕,我很高兴它会发生,因为希望我能够修复另一个依赖).
我已经在我的机器上启动了整个测试包,并且我已经获得了与集成系统相同的结果.到目前为止一直很好,现在我开始关闭测试,直到我缩小了一个干扰最近添加的测试的测试.他们没有任何共同之处.我已经深入挖掘,并将问题缩小到一条线.如果我评论它 - 测试通过,如果没有 - 测试失败.
问题
我们有这样的代码将文本数据转换为经度坐标(仅包括重要部分):
procedure TTerminalNVCParserTest_Unit.TranslateGPS_ValidGPSString_ReturnsValidCoords;
const
CStrGPS = 'N5145.37936E01511.8029';
var
LLatitude, LLongitude: Integer;
LLong: Double;
LStrLong, LTmpStr: String;
LFS: TFormatSettings;
begin
FillChar(LFS, SizeOf(LFS), 0);
LFS.DecimalSeparator := '.';
LStrLong := Copy(CStrGPS, Pos('E', CStrGPS)+1, 10);
LTmpStr := Copy(LStrLong,1,3);
LLong := StrToFloatDef( LTmpStr, 0, LFS );
LTmpStr := Copy(LStrLong,4,10);
LLong := LLong + StrToFloatDef( LTmpStr, 0, LFS)*1/60;
LLongitude := Round(LLong * 100000);
CheckEquals(1519671, LLongitude);
end;
Run Code Online (Sandbox Code Playgroud)
问题是LLongitude有时等于1519671,有时它给出1519672.并且它是否给出1519672是否依赖于不同测试中不同方法中其他完全不相关的代码片段:
FormXtrMainImport.JvWizard1.SelectNextPage;
Run Code Online (Sandbox Code Playgroud)
我检查了SelectNextPage方法的四倍,它不会触发任何可能改变FPU单元工作方式的事件.它不会改变它的值RoundingMode总是在rmNearest上设置.
此外,德尔福不应该在这里使用银行家规则吗?:
LLongitude …Run Code Online (Sandbox Code Playgroud) delphi floating-point unit-testing type-conversion delphi-2009
之情况:
我想在运行时向给定(任意)数据集添加计算字段.除了执行DataSet.Open方法之外,我不知道获取数据集结构的任何其他方法.
但是该Open方法导致至少一行数据需要从服务器转移到客户端.然后我需要关闭DataSet,添加字段并重新打开它.在我看来,这是一个不必要的开销.有没有更好的方法呢?请注意,我不希望能够为任何数据集添加计算字段,并且在打开之前我不知道它的结构.
在伪代码中它看起来像这样:
DataSet.Open;
DataSet.Close;
RecreateFieldsStructure;
AddCalculatedField;
DataSet.Open;
Run Code Online (Sandbox Code Playgroud)
谢谢你的时间.
最近我有一个dillema.
考虑这样的例子:
unit Unit2;
interface
uses
Classes;
type
TMyObject = class(TObject)
private
FDataStream: TMemoryStream;
procedure SetDataStream(const Value: TMemoryStream);
public
property DataStream: TMemoryStream read FDataStream write SetDataStream;
constructor Create(ADataStream: TMemoryStream);
destructor Destroy;
end;
implementation
{ TMyObject }
constructor TMyObject.Create(ADataStream: TMemoryStream);
begin
FDataStream := ADataStream;
end;
destructor TMyObject.Destroy;
begin
//Should MyObject free FDataStream?
end;
procedure TMyObject.SetDataStream(const Value: TMemoryStream);
begin
FDataStream := Value;
end;
end.
Run Code Online (Sandbox Code Playgroud)
如您所见,TMyObject可以有一个TMemoryStream实例.现在,我想知道TMyobject在被释放时应该做什么?它是否还应该释放FDataStram还是它应该保留原样?
这样的场景是否有任何指导?
谢谢.
delphi ×8
delphi-2009 ×5
c# ×2
ado ×1
class ×1
cloning ×1
dataset ×1
field ×1
generics ×1
singleton ×1
tadodataset ×1
tadoquery ×1
types ×1
unit-testing ×1