Class DataModel
A class
representing an abstract data model that can be easily
encoded and decoded to and from a
Inheriting this class and simply declaring properties allows an instance of the child class
to encode its data into a
However, there are certain restrictions that apply when using this class
:
-
The complete list of allowed property types are as follows:
-
Primitive types:
bool
,int
,long
,BigInteger
,ImmutableArray<byte>
,Guid
,Address
, andstring
. - Special types: Any type inherited from DataModel.
-
Collective types:
-
where T
is a primitive type. -
where -
TKey
is one ofImmutableArray<byte>
,Address
,Guid
, andstring
. -
TValue
is a primitive type.
-
-
-
Primitive types:
-
Value types are not allowed to be declared as
nullable
, not even as a generic type parameter. That is, types such asbool?
,Address?
, andImmutableList<int?>
are not allowed. -
Reference types are not allowed to be assigned
null
. This will result in anwhen Encode() is called. -
Trying to assign
null
to any property or to a part of a collection will result in anwhen DataModel(Bencodex.Types.Dictionary) is called.
Namespace: Libplanet.Store
Assembly: Libplanet.dll
Syntax
public abstract class DataModel : object
Remarks
There are certain caveats for using this class:
-
Encoded data type is fixed to
. As each property name is encoded into as a key, it is advisable to give short names for properties. For example, int HP
is better thanint HealthPoint
to reduce storage size and/or network traffic. As seen in the example above, actively use documented properties instead. -
Property type of
is inefficient to encode and decode. Additional caution is needed when declaring property type. - As supported types are limited, in particular, nullable types and nested collection types not being allowed, if a custom data model that isn't supported by this class is needed, manual implementation of encoding and decoding should be done separately.
Examples
The following example shows how this class can be used:
public class CharacterData : DataModel
{
/// <summary>
/// Name of the character.
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Current level of the character.
/// </summary>
public int Level { get; private set; }
/// <summary>
/// Inventory of the character.
/// </summary>
public InventoryData Inv { get; private set; }
public CharacterData(string name, int level, InventoryData inv)
: base()
{
Name = name;
Level = level;
Inv = inv;
}
public CharacterData(Bencodex.Types.Dictionary encoded)
: base(encoded)
{
}
}
public class InventoryData : DataModel
{
/// <summary>
/// The amount of gold in the inventory.
/// </summary>
public int Gold { get; private set; }
public InventoryData(int gold)
: base()
{
Gold = gold;
}
public InventoryData(Bencodex.Types.Dictionary encoded)
: base(encoded)
{
}
}
Then the concrete model defined above can be used as shown below:
CharacterData characterData = new CharacterData("John", 5, new InventoryData(100));
Bencodex.Types.Dictionary encoded = characterData.Encode()
This would result in encoded
in a following format:
Bencodex.Types.Dictionary {
"Name": "John",
"Level": 5,
"Inv": {
"Gold": 100,
},
}
To decode this back into an instance, simply use it as shown below:
CharacterData decoded = new CharacterData(encoded);
Then decoded.Name
, decoded.Level
, and decoded.Inv.Gold
will have
values "John"
, 5
, and 100
respectively.
Constructors
| Improve this Doc View SourceDataModel()
Declaration
protected DataModel()
DataModel(Bencodex.Types.Dictionary)
Decodes a
Declaration
protected DataModel(Bencodex.Types.Dictionary encoded)
Parameters
Type | Name | Description |
---|---|---|
Bencodex.Types.Dictionary | encoded | The |
Methods
| Improve this Doc View SourceEncode()
Encodes an instance into a
Declaration
public Bencodex.Types.Dictionary Encode()
Returns
Type | Description |
---|---|
Bencodex.Types.Dictionary | An encoded |