asyncapi / asyncapi/modelina

[BUG] C#: `const` properties emit invalid `public const T X { get; } = ...` with auto-implemented properties

Open Beginner friendly
#2,591 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
448
Forks
242
Avg merge
15m
Merged PRs (30d)
7

Description

## Description

When generating C# models for a property declared with `const` in the schema, the **C# generator with auto-implemented properties enabled** (`autoImplementedProperties: true`, e.g. the `--csharpAutoImplement` CLI flag, commonly combined with `--csharpNewtonsoft`) renders an **invalid property declaration** that does not compile:

```csharp
public const string EventType { get; } = "OnEntryStarted";
```

A C# `const` field cannot have property accessors (`{ get; }`). This is a compile error (e.g. `CS0107`/syntax error) — a `const` is a field, not a property.

This is a separate problem from the read-only assignment issue tracked in #2589, but both must be fixed for `const` properties to compile under the Newtonsoft preset (see "Related" below).

## How to reproduce

```js
import { CSharpGenerator } from '@asyncapi/modelina';

const generator = new CSharpGenerator({ autoImplementedProperties: true });

const schema = {
$id: 'Event',
type: 'object',
properties: { eventType: { type: 'string', const: 'OnEntryStarted' } },
required: ['eventType'],
};

const models = await generator.generate(schema);
for (const m of models) console.log(m.result);
```

CLI equivalent:

```sh
asyncapi generate models csharp ./event.yaml -o ./out --namespace MyNs --csharpAutoImplement --csharpNewtonsoft
```

## Generated output — does not compile

```csharp
public partial class Event
{
public const string EventType { get; } = "OnEntryStarted";
}
```

## Expected behavior

A `const` property should be rendered as a plain const field (matching what the `record` renderer already produces):

```csharp
public const string EventType = "OnEntryStarted";
```

## Root cause

In `src/generators/csharp/renderers/ClassRenderer.ts`, the auto-implemented-properties branch of the `property` preset emits the `const` declaration with `{ ${getter} }` accessors. The `record` preset (`RecordRenderer.ts`) already renders the same case correctly without accessors.

## Related

- #2589 — Newtonsoft `ReadJson` assigns to the (read-only) `const` property → `CS0200`/`CS0131`. Even after fixing this declaration bug, the Newtonsoft converter still emits a non-compiling assignment, so both need to be addressed for `--csharpNewtonsoft` + `const` output to compile.

## Environment

- Modelina: 5.10.1

Contributor guide

Open the contributing guide

Research direction

Start in src/generators/csharp/renderers/ClassRenderer.ts and compare the const-property branch with the working case in RecordRenderer.ts. Reproduce with CSharpGenerator using autoImplementedProperties: true, or the --csharpAutoImplement and --csharpNewtonsoft CLI flags; done means the generated declaration is a plain const field without accessors and compiles as shown.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, typescript
Domain
tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.