1Use in C# {#flatbuffers_guide_use_c-sharp} 2============== 3 4## Before you get started 5 6Before diving into the FlatBuffers usage in C#, it should be noted that 7the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to 8general FlatBuffers usage in all of the supported languages (including C#). 9This page is designed to cover the nuances of FlatBuffers usage, 10specific to C#. 11 12You should also have read the [Building](@ref flatbuffers_guide_building) 13documentation to build `flatc` and should be familiar with 14[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and 15[Writing a schema](@ref flatbuffers_guide_writing_schema). 16 17## FlatBuffers C-sharp code location 18 19The code for the FlatBuffers C# library can be found at 20`flatbuffers/net/FlatBuffers`. You can browse the library on the 21[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/ 22FlatBuffers). 23 24## Testing the FlatBuffers C-sharp libraries 25 26The code to test the libraries can be found at `flatbuffers/tests`. 27 28The test code for C# is located in the [FlatBuffers.Test](https://github.com/ 29google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the 30tests, open `FlatBuffers.Test.csproj` in [Visual Studio]( 31https://www.visualstudio.com), and compile/run the project. 32 33Optionally, you can run this using [Mono](http://www.mono-project.com/) instead. 34Once you have installed `Mono`, you can run the tests from the command line 35by running the following commands from inside the `FlatBuffers.Test` folder: 36 37~~~{.sh} 38 mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs 39 mono Assert.exe 40~~~ 41 42## Using the FlatBuffers C# library 43 44*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth 45example of how to use FlatBuffers in C#.* 46 47FlatBuffers supports reading and writing binary FlatBuffers in C#. 48 49To use FlatBuffers in your own code, first generate C# classes from your 50schema with the `--csharp` option to `flatc`. 51Then you can include both FlatBuffers and the generated code to read 52or write a FlatBuffer. 53 54For example, here is how you would read a FlatBuffer binary file in C#: 55First, import the library and generated code. Then, you read a FlatBuffer binary 56file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you 57pass to the `GetRootAsMyRootType` function: 58 59~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs} 60 using MyGame.Example; 61 using FlatBuffers; 62 63 // This snippet ignores exceptions for brevity. 64 byte[] data = File.ReadAllBytes("monsterdata_test.mon"); 65 66 ByteBuffer bb = new ByteBuffer(data); 67 Monster monster = Monster.GetRootAsMonster(bb); 68~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 70Now you can access the data from the `Monster monster`: 71 72~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs} 73 short hp = monster.Hp; 74 Vec3 pos = monster.Pos; 75~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 76 77C# code naming follows standard C# style with `PascalCasing` identifiers, 78e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are 79available as properties instead of parameterless accessor methods. 80The performance-enhancing methods to which you can pass an already created 81object are prefixed with `Get`, e.g.: 82 83~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs} 84 // property 85 var pos = monster.Pos; 86 87 // method filling a preconstructed object 88 var preconstructedPos = new Vec3(); 89 monster.GetPos(preconstructedPos); 90~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 91 92## Storing dictionaries in a FlatBuffer 93 94FlatBuffers doesn't support dictionaries natively, but there is support to 95emulate their behavior with vectors and binary search, which means you 96can have fast lookups directly from a FlatBuffer without having to unpack 97your data into a `Dictionary` or similar. 98 99To use it: 100- Designate one of the fields in a table as the "key" field. You do this 101 by setting the `key` attribute on this field, e.g. 102 `name:string (key)`. 103 You may only have one key field, and it must be of string or scalar type. 104- Write out tables of this type as usual, collect their offsets in an 105 array. 106- Instead of calling standard generated method, 107 e.g.: `Monster.createTestarrayoftablesVector`, 108 call `CreateSortedVectorOfMonster` in C# 109 which will first sort all offsets such that the tables they refer to 110 are sorted by the key field, then serialize it. 111- Now when you're accessing the FlatBuffer, you can use 112 the `ByKey` accessor to access elements of the vector, e.g.: 113 `monster.TestarrayoftablesByKey("Frodo")` in C#, 114 which returns an object of the corresponding table type, 115 or `null` if not found. 116 `ByKey` performs a binary search, so should have a similar 117 speed to `Dictionary`, though may be faster because of better caching. 118 `ByKey` only works if the vector has been sorted, it will 119 likely not find elements if it hasn't been sorted. 120 121## Text parsing 122 123There currently is no support for parsing text (Schema's and JSON) directly 124from C#, though you could use the C++ parser through native call 125interfaces available to each language. Please see the 126C++ documentation for more on text parsing. 127 128## Object based API 129 130FlatBuffers is all about memory efficiency, which is why its base API is written 131around using as little as possible of it. This does make the API clumsier 132(requiring pre-order construction of all data, and making mutation harder). 133 134For times when efficiency is less important a more convenient object based API 135can be used (through `--gen-object-api`) that is able to unpack & pack a 136FlatBuffer into objects and standard System.Collections.Generic containers, allowing for convenient 137construction, access and mutation. 138 139To use: 140 141~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs} 142 // Deserialize from buffer into object. 143 MonsterT monsterobj = GetMonster(flatbuffer).UnPack(); 144 145 // Update object directly like a C# class instance. 146 Console.WriteLine(monsterobj.Name); 147 monsterobj.Name = "Bob"; // Change the name. 148 149 // Serialize into new flatbuffer. 150 FlatBufferBuilder fbb = new FlatBufferBuilder(1); 151 fbb.Finish(Monster.Pack(fbb, monsterobj).Value); 152~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 153 154### Json Serialization 155 156An additional feature of the object API is the ability to allow you to 157serialize & deserialize a JSON text. 158To use Json Serialization, add `--gen-json-serializer` option to `flatc` and 159add `Newtonsoft.Json` nuget package to csproj. 160 161~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs} 162 // Deserialize MonsterT from json 163 string jsonText = File.ReadAllText(@"Resources/monsterdata_test.json"); 164 MonsterT mon = MonsterT.DeserializeFromJson(jsonText); 165 166 // Serialize MonsterT to json 167 string jsonText2 = mon.SerializeToJson(); 168~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 169 170* Limitation 171 * `hash` attribute currentry not supported. 172* NuGet package Dependency 173 * [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) 174 175<br> 176