Open koczkatamas opened 7 years ago
Actually renaming inner classes looks like as a better solution. It's very convenient to use the class name as property name in multiple cases...
And probably it's not worth to deny this opportunity from other languages because of one language.
But I have no idea for a good renaming rule. Maybe appending "Struct" or "KS"?
I started implementing a workaround but it gets messy fast: https://github.com/kaitai-io/kaitai_struct_compiler/commit/918d4ccfd9df11b0a30b6cec08e1e65fe1991cea
The same problem happens with enums too, but I cannot easily overwrite enum names...
Here is a bit complex .ksy:
Currently this C# file is generated:
The Hdr1, Hdr2, Hdr1.Type and Hdr2.Type names conflict as there is a nested class / enum and a property with the same name (both are members of the same class).
As far as I know it's a generic advice to use namespaces instead of nested classes (using works on them), this gives us a structure something like this:
With a bit more complex logic we can generate a bit more nature code.
I created (manually) the code below using this logic:
enums
or types
definition then we use a namespace around it (with the same name, eg. NameConflict.NameConflict
or Hdr1.Hdr1
).The pros of this solution:
XYTypes
namespacesusing
a namespace includes the class and every used subtypes and enums for that typeI also took the opportunity to modify the order of properties, methods, constructors and static parse methods. Also removed the unnecessary backing fields (still using C# 2.0).
What do you think @LogicAndTrick & @GreyCat how does it look?
Looks like a good idea. I can't see any obvious downsides, aside from the compiler being a bit more complex. There's still going to be possible conflicts with class names and property names but they are probably less common:
types:
test:
seq:
- id: test
type: s4
public class Test
{
// CS0542 'Test': member names cannot be the same as their enclosing type
public int Test { get; set; }
}
A note for the future when this is being worked on.
@koczkatamas (https://github.com/kaitai-io/kaitai_struct/issues/86#issuecomment-292667485):
With a bit more complex logic we can generate a bit more nature code.
I created (manually) the code below using this logic:
- if the type has
enums
ortypes
definition then we use a namespace around it (with the same name, eg.NameConflict.NameConflict
orHdr1.Hdr1
).- otherwise we can put into the parent's namespace (optional)
(...)
NameConflict.cs (click to open)
We should not use this solution, because naming a class the same as its namespace is actually explicitly discouraged by the C# community - see https://stackoverflow.com/a/2850148/12940655 and a 4-part article series "Do not name a class the same as its namespace" by Eric Lippert:
The generated C# code from this .ksy won't compile:
The C# compiler throws the following error message:
This is not an issue in ... because ...
mz_header_t
, private field =m_mz_header
, getter =mz_header()
MzHeader
, private field =mzHeader
, getter =mzHeader()
MzHeader
, field =mzHeader
(also instance vs static?)MzHeader
, field =mz_header
(also instance vs static?)MzHeader
, private field =_m_mzHeader
, getter =mzHeader()
MzHeader
, field =mzHeader
MzHeader
, field =mzHeader
Summary: only C# uses UpperCase properties.
Other solution could be renaming subclasses if we detect a conflict.