如何使用bit / bit-operator来控制对象状态?

时间:2009-02-05 16:25:46

标签: delphi bitwise-operators object-state

我想创建轻量级对象数据包,以便在客户端和服务器应用程序之间传递。

这是一项非常简单的任务,我只能控制1个字节,所以 一个字节中的每个位都有不同的含义,

仅使用位

0 = False 
1 = True

现在我需要:

1 - Loaded from database 
2 - Persisted
3 - Changed
4 - Marked to Delete
5 -
6 - 
7 - Null Value 
8 - Read Only


1) How do I use bit operators in Delphi to check each bit value? 
2) How do I set the bit Values?

解决方案

在所有帮助之后,我会使用下一个Set

  TStateType = (
    stLoaded    = 0,   // loaded from persistance
    stNative    = 2,   // value loaded and converted to native type
    stPersisted = 3,   // saved
    stChanged   = 4,   // object or member changed
    stToDelete  = 5,   // marked to delete
    stReadOnly  = 6,   // read only object, will not allow changes
    stNull      = 7    // value is null
  );
  TState = Set of TStateType;

对于流 - >坚持,这将是使用的记录:

  TDataPackage = record
    Data: TBytes;
    TypeInfo: TMetaInfo;
    State: Byte;
    Instance: TBuffer;
  end;

谢谢伙伴们,获取所有答案和评论。

3 个答案:

答案 0 :(得分:7)

我真的使用了一套。但是,我看到你真的想要一个字节。在任何地方使用集合,然后在最后将类型转换为一个字节。

这个解决方案需要更少的输入,支持标准的delphi运算符,并且实际上没有性能损失,正如Barry Kelly指出的那样。

procedure Test;
type
  TSetValues = (
    TSetValue1   = 0,
    TSetValue2   = 1,
    TSetValue4   = 2,
    TSetValue8   = 3,
    TSetValue16  = 4,
    TSetValue32  = 5,
    TSetValue64  = 6,
    TSetValue128 = 7
  );

  TMySet = set of TSetValues;
var
  myValue: byte;
  mySet: TMySet;
begin
  mySet := [TSetValue2, TSetValue16, TSetValue128];
  myValue := byte(mySet);
  ShowMessage(IntToStr(myValue)); // <-- shows 146
end;

答案 1 :(得分:6)

我会使用一套:

type
    TMyDatum = (mdLoaded, mdPersisted, mdChanged, mdMarkedToDelete, ...);
    TMyData = set of TMyDatum;

var
  Foo: TMyData;
begin 
  Foo := [mdLoaded, mdChanged];
  if (mdPersisted in Foo) then ...

这些是作为整数实现的,因此您可以轻松地传递它们。我发现代码比按位运算符更容易阅读。

答案 2 :(得分:1)

This page描述了Delphi运算符,包括按位运算符。

听起来你需要使用和运算符。例如:

const
  LOADED_FROM_DATABASE = 1;
  PERSISTED = 2;
  CHANGED = 4;
  // etc...

//...

if (bitFlags and LOADED_FROM_DATABASE) <> 0 then
begin
  // handle LOADED FROM DATABASE
end;

if (bitFlags and PERSISTED) <> 0 then
begin
  // handle PERSISTED
end;

// etc...

为了设置标志,您可以使用OR:

bitFlags := LOADED_FROM_DATABASE or PERSISTED or CHANGED;