Navigation

Field Types - .NET SDK

Realm Database supports the following property data types and their nullable counterparts:

  • bool
  • byte
  • short
  • int
  • long
  • float
  • double
  • decimal
  • char
  • string
  • byte[]
  • DateTimeOffset
  • Decimal128 from MongoDB.Bson
  • ObjectId from MongoDB.Bson
  • RealmInteger<T> (see below)
  • A RealmObject subclass
  • An EmbeddedObject subclass (see Embedded Objects)
  • IList<T> where T is any of the previous data types (see Lists)

The byte, char, short, int, and long types are all stored as 64 bit integer values within Realm Database.

If you choose to provide custom constructors, you must declare a public constructor with no arguments.

Realm offers RealmInteger as a special integer type to be used as a logical counter. RealmInteger<T> exposes an additional API that can more clearly express intent and generate better conflict resolution steps when using Synchronized Realms. The type argument <T> can be of type byte, short, int, or long. The following example shows how to use a RealmInteger property that maps to an int:

public class MyRealmClass : RealmObject
{
[PrimaryKey]
public int _id { get; set; }
public RealmInteger<int> Counter { get; set; }
}

Traditionally, you would implement a counter by reading a value, incrementing it, and then setting it (myObject.Counter += 1). This does not work well in an asynchronous situation like when two clients are offline. Consider the following scenario:

  • The realm object has a counter property of type int. It is currently set to a value of 10.
  • Clients 1 and 2 both read the counter property (10) and each increments the value by 1.
  • When each client regains connectivity and merges their changes, they expect a value of 11, and there is no conflict. However, the counter value should be 12!

When using a RealmInteger, however, you can call the Increment() and Decrement() methods, and to reset the counter, you set it to 0, just as you would an int:

var myObject = realm.Find<MyRealmClass>(id);
var counter = myObject.Counter; // 0
realm.Write(() =>
{
// Increment the value of the RealmInteger
myObject.Counter.Increment(); // 1
myObject.Counter.Increment(5); // 6
// Decrement the value of the RealmInteger
// Note the use of Increment with a negative number
myObject.Counter.Decrement(); // 5
myObject.Counter.Increment(-3); // 2
// Reset the RealmInteger
myObject.Counter = 0;
// RealmInteger<T> is implicitly convertable to T:
int bar = myObject.Counter;
Important

When you reset a RealmInteger, you may run into the offline merge issue described above.

A RealmInteger is backed by traditional integer type, so no schema migration is required when changing a property type from T to RealmInteger<T>.

Realm supports 128-bit decimal values with the Decimal128 Bson type. When defining a decimal type, you can use the Decimal128 Bson type or the .NET decimal type, even though it is only a 96-bit decimal. The SDK automatically converts between the two, although you risk losing precision or range. The following example shows how to use both the Decimal128 Bson type and the .NET decimal type:

public class MyClassWithDecimals {
[PrimaryKey]
public ObjectId _id { get; } = ObjectId.GenerateNewId();
// Standard (96-bit) decimal value type
public decimal VeryPreciseNumber { get; set; }
// 128-bit Decimal128
public Decimal128 EvenMorePreciseNumber { get; set; }
public Decimal128 AnotherEvenMorePreciseNumber { get; set; }
// Nullable decimal or Decimal128 are supported, too
public decimal? MaybeDecimal { get; set; }
public Decimal128? MaybeDecimal128 { get; set; }
public void PlayWithDecimals()
{
var myInstance = new MyClassWithDecimals();
// To store decimal values:
realm.Write(() =>
{
myInstance.VeryPreciseNumber = 1.234567890123456789M;
myInstance.EvenMorePreciseNumber = Decimal128.Parse("987654321.123456789");
// Decimal128 has explicit constructors that take a float or a double
myInstance.EvenMorePreciseNumber = new Decimal128(9.99999);
});
}
}
Give Feedback