Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@naine
Copy link
Contributor

@naine naine commented Jul 25, 2019

Follow-up to #5419

The C# ByteBuffer class features a number of generic methods which are employed mostly when dealing with vectors. The generic methods work using a static table of type sizes, and do not support any type not in the table, including the enum types generated from flatbuffer schemas. They also use the Buffer.BlockCopy method to copy directly between the backing byte array and strongly typed arrays returned to or supplied from the user, and this method does not work with enum-typed arrays.

The C# code generator works around ByteBuffer's lack of support for enum types by casting to/from the generated enum types when using the various Get*/Put* methods for reading/writing individual integer values. But for some generated code this work-around is not applicable, and flatc generates code which invokes the generic ByteBuffer methods using enum types, which will always throw at runtime.

I considered first attempting to address the limitations in ByteBuffer instead, but saw no way to do this without negatively impacting either performance or compatibility.

My solution modifies the generator to avoid calling the generic methods with enum types:

  • Generated static Create*VectorBlock() methods now delegate to their Create*Vector() counterparts, which are semantically identical but slower. They should really be removed but I kept them there for backwards compatibility.
  • Generated Get*Array() methods now directly create an array and copy data into it in a loop instead of calling __vector_as_array<T>(). Data is read into the array the same way the standard accessors for enum vectors read from the buffer, by using a specific Get*() method and casting to the enum type. The loop is roughly modelled after similar loops generated in Create*Vector() methods.

@aardappel
Copy link
Collaborator

The code duplication is unfortunate, but if this makes the code more compatible with all possible types, that is probably essential.

Should we somehow mark the Block versions as deprecated, and document they are intended to be removed in a future release?

@naine
Copy link
Contributor Author

naine commented Jul 26, 2019

There is System.ObsoleteAttribute which makes it a compiler warning to reference the method, and there is System.ComponentModel.EditorBrowsableAttribute which hides the method from an IDE's API browser.

But on second thought, I think we should just stop generating them now for vectors of enums, considering that they never worked in the first place. I doubt anyone is relying on their existence.

Your thoughts?

@aardappel
Copy link
Collaborator

Yup, if before they produced errors when used in that combination, remove them.

But still good to mark them as deprecated. The former attribute sounds right to me.

@aardappel
Copy link
Collaborator

Are you going to mark it deprecated?

@naine
Copy link
Contributor Author

naine commented Jul 26, 2019

No, I can't mark generated code deprecated if it's removed.

@aardappel
Copy link
Collaborator

I was referring to the non-enum Block functions.

@naine
Copy link
Contributor Author

naine commented Jul 26, 2019

Oh. Well I don't think there is a particular need to deprecate it in other cases. They still provide a slight performance increase where they work.

@naine
Copy link
Contributor Author

naine commented Sep 2, 2019

Hi @aardappel, can I get an update on whether this can be accepted?

@aardappel
Copy link
Collaborator

@naine As I said, I was wondering wether you were going to mark the non-enum Block functions as deprecated?

@naine
Copy link
Contributor Author

naine commented Sep 3, 2019

They offer a performance boost for primitive types so I wasn't planning to, no.

Do you disagree with this?

@aardappel
Copy link
Collaborator

Ok, I guess I misunderstood our previous discussion then.

Thanks :)

@aardappel aardappel merged commit d0e3870 into google:master Sep 3, 2019
LuckyRu pushed a commit to LuckyRu/flatbuffers that referenced this pull request Oct 2, 2020
* [C#] Fix retrieving enumeration vectors as arrays

* [C#] Don't generate CreateVectorBlock for enums
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants