Skip to content

Commit 1c9b029

Browse files
committed
Merge remote-tracking branch 'origin/csharp-0.4-dev'
2 parents dfe1056 + 27867fe commit 1c9b029

File tree

4 files changed

+118
-91
lines changed

4 files changed

+118
-91
lines changed

content/slice/language-guide/class-types.md

+43-16
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,15 @@ example:
4444
```slice
4545
class CarPart {
4646
id: string
47+
revision: int32
4748
}
4849
4950
class RearBumper : CarPart {
5051
color: Color
5152
}
5253
```
5354

54-
`RearBumper` has two fields: `id` (inherited from `CartPart`) and `color`.
55+
`RearBumper` has three fields: `id` and `revision` (inherited from `CartPart`) and `color`.
5556

5657
A derived class cannot redefine a field of its base class: all the fields must have unique names.
5758

@@ -210,64 +211,90 @@ For example:
210211
```slice
211212
class CarPart {
212213
id: string
214+
revision: int32
213215
tag(1) shippingWeight: float64?
214216
}
215217
```
216218

217219
```csharp
218220
public partial class CarPart : SliceClass
219221
{
220-
public string Id;
221-
public double? ShippingWeight;
222+
public required string Id { get; set; }
223+
224+
public int Revision { get; set; }
225+
226+
public double? ShippingWeight { get; set; }
227+
228+
// Parameterless constructor
229+
public CarPart()
230+
{
231+
}
222232

223233
// Primary constructor
224-
public CarPart(string id, double? shippingWeight)
234+
public CarPart(
235+
string id,
236+
int revision,
237+
double? shippingWeight)
225238
{
226-
...
239+
this.Id = id;
240+
this.Revision = revision;
241+
this.ShippingWeight = shippingWeight;
227242
}
228243

229244
// Secondary constructor
230-
public CarPart(string id)
245+
public CarPart(string id, int revision)
231246
{
232-
...
247+
this.Id = id;
248+
this.Revision = revision;
233249
}
234-
235250
}
236251
```
237252

238253
{% /aside %}
239254

240-
The mapped class has a primary constructor which sets all the fields. If any field has an optional type, the mapped
241-
class has a second constructor with a parameter for each non-nullable C# field.
255+
The mapped C# class provides a parameterless constructor and a primary constructor which sets all the fields. If any
256+
field has an optional type, the mapped class also provides a secondary constructor with a parameter for each
257+
non-nullable C# field.
242258

243-
Slice class inheritance maps the C# class inheritance as you would expect:
259+
Slice class inheritance maps to C# class inheritance as you would expect:
244260

245261
{% aside alignment="top" %}
246262

247263
```slice
248-
class FrontBumper : CarPart {
264+
class RearBumper : CarPart {
249265
color: Color
250266
}
251267
```
252268

253269
```csharp
254270
public partial class RearBumper : CarPart
255271
{
256-
public Color Color;
272+
public Color Color { get; set; }
273+
274+
// Parameterless constructor
275+
public RearBumper()
276+
{
277+
}
257278

258279
// Primary constructor
259280
public RearBumper(
260281
string id,
282+
int revision,
261283
double? shippingWeight,
262284
Color color)
285+
: base(id, revision, shippingWeight)
263286
{
264-
...
287+
this.Color = color;
265288
}
266289

267290
// Secondary constructor
268-
public RearBumper(string id, Color color)
291+
public RearBumper(
292+
string id,
293+
int revision,
294+
Color color)
295+
: base(id, revision)
269296
{
270-
...
297+
this.Color = color;
271298
}
272299
}
273300
```

content/slice/language-guide/exception.md

+37-51
Original file line numberDiff line numberDiff line change
@@ -76,29 +76,40 @@ exception TranslationException {
7676
```
7777

7878
```csharp
79-
public partial class TranslationException
80-
: SliceException
79+
public partial class TranslationException :
80+
SliceException
8181
{
82-
public TranslationErrorCode ErrorCode;
83-
public string? DetectedLanguage;
82+
public TranslationErrorCode ErrorCode { get; set; }
83+
public string? DetectedLanguage { get; set; }
84+
85+
// Parameterless constructor
86+
public TranslationException()
87+
{
88+
}
8489

8590
// Primary constructor
8691
public TranslationException(
8792
TranslationErrorCode errorCode,
88-
string? detectedLanguage,
89-
string? message = null,
90-
System.Exception? innerException = null)
91-
: base(message, innerException)
93+
string? detectedLanguage)
94+
{
95+
this.ErrorCode = errorCode;
96+
this.DetectedLanguage = detectedLanguage;
97+
}
98+
99+
// Secondary constructor
100+
public TranslationException(
101+
TranslationErrorCode errorCode)
92102
{
93-
...
103+
this.ErrorCode = errorCode;
94104
}
95105
}
96106
```
97107

98108
{% /aside %}
99109

100-
The mapped C# class provides a primary constructor with parameters for all its fields, plus an optional message and an
101-
optional inner exception (like most exceptions in C#).
110+
The mapped C# class provides a parameterless constructor and a primary constructor which sets all the fields. If any
111+
field has an optional type, the mapped class also provides a secondary constructor with a parameter for each
112+
non-nullable C# field.
102113

103114
Slice exception inheritance maps to C# class inheritance:
104115

@@ -117,66 +128,41 @@ exception DerivedException : BaseException {
117128
```csharp
118129
public partial class BaseException : SliceException
119130
{
120-
public int ErrorCode;
131+
public int ErrorCode { get; set; }
121132

122-
// Primary constructor
123-
public BaseException(
124-
int errorCode,
125-
string? message = null,
126-
System.Exception? innerException = null)
127-
: base(message, innerException)
133+
public BaseException()
134+
{
135+
}
136+
137+
public BaseException(int errorCode)
128138
{
129-
...
139+
this.ErrorCode = errorCode;
130140
}
131141
}
132142

133143
public partial class DerivedException : BaseException
134144
{
135-
public double Measurement;
145+
public double Measurement { get; set; }
146+
147+
public DerivedException()
148+
{
149+
}
136150

137-
// Primary constructor.
138151
public DerivedException(
139152
int errorCode,
140-
double measurement,
141-
string? message = null,
142-
System.Exception? innerException = null)
143-
: base(errorCode, message, innerException)
153+
double measurement)
154+
: base(errorCode)
144155
{
145-
...
156+
this.Measurement = measurement;
146157
}
147158
}
148159
```
149160

150161
{% /aside %}
151162

152-
### ConvertToInternalError
153-
154-
When the generated code decodes an exception from a payload, it sets the exception's
155-
[ConvertToInternalError][convert-to-internal-error] property to `true`.
156-
157-
This way, when the implementation of an operation makes an invocation and this invocation throws an exception, by
158-
default, this exception is not re-sent as-is but gets converted into a response with status code
159-
[InternalError]. If you don't want this conversion, you need to catch the exception and set
160-
`ConvertToInternalError` to `false`:
161-
162-
```csharp
163-
try
164-
{
165-
...make invocation...
166-
}
167-
catch (DispatchException exception)
168-
{
169-
// Don't convert to internal error.
170-
exception.ConvertToInternalError = false;
171-
throw;
172-
}
173-
```
174-
175-
[convert-to-internal-error]: csharp:IceRpc.DispatchException#IceRpc_DispatchException_ConvertToInternalError
176163
[exception-specification]: operation#exception-specification
177164
[sliced-format]: class-types#slicing
178165

179166
[SliceException]: csharp:ZeroC.Slice.SliceException
180-
[InternalError]: csharp:IceRpc.StatusCode#IceRpc_StatusCode_InternalError
181167

182168
{% /slice1 %}

content/slice/language-guide/fields.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ and `Dictionary<int32, string>` are constructed types.
3030
When you define a field, you can specify whether this field must hold a value of its type, or if holding a special "not
3131
set" value is also acceptable. In this latter situation, you would give the field an optional type, with a `?` suffix.
3232

33-
This special "not set" value corresponds to null in C#, `std::nullopt` in C++, nil in Swift, etc.
33+
This special "not set" value corresponds to `null` in C#, `std::nullopt` in C++, `nil` in Swift, etc.
3434

3535
For example:
3636

@@ -58,11 +58,11 @@ Leaving tagged fields aside, only a few field types can be marked optional with
5858
```slice
5959
struct Person {
6060
name: string
61-
dataOfBirth: WellKnownTypes::TimeStamp?
61+
dateOfBirth: WellKnownTypes::TimeStamp?
6262
}
6363
```
6464

65-
The field `dataOfBirth` may have a value or a "not set" value (when the date of birth is unknown).
65+
The field `dateOfBirth` may have a value or a "not set" value (when the date of birth is unknown).
6666
{% /slice2 %}
6767

6868
{% callout %}
@@ -185,8 +185,12 @@ applications that expect tag 7 fields (in this tag number scope) to be encoded a
185185

186186
## C# mapping
187187

188-
A field `name: Type` is mapped to a C# field with the same name, with name converted to Pascal case. The type of the C#
189-
field is the mapped C# type for `Type`.
188+
A field `name: Type` is mapped to a C# property with the same name, with name converted to Pascal case. The type of the
189+
C# property is the mapped C# type for `Type`.
190+
191+
When a Slice field type maps to a non-nullable C# reference type (for example, a C# string), the mapped property is
192+
"required". This ensures you provide a value for this property during construction or initialization of the enclosing
193+
type.
190194

191195
Tagged fields are mapped just like regular fields. The tag and tag number don't appear in the mapped C# API.
192196

content/slice/language-guide/struct-types.md

+29-19
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ compact struct PostalAddress {
8282
```csharp
8383
public partial record struct PostalAddress
8484
{
85-
public string RecipientFullName;
86-
public string StreetAddress1;
87-
public string StreetAddress2;
88-
public string City;
89-
public StateAbbreviation State;
90-
public string Zip;
85+
public required string RecipientFullName { get; set; }
86+
public required string StreetAddress1 { get; set; }
87+
public required string StreetAddress2 { get; set; }
88+
public required string City { get; set; }
89+
public StateAbbreviation State { get; set; }
90+
public required string Zip { get; set; }
9191

9292
// Primary constructor.
9393
public PostalAddress(
@@ -98,7 +98,12 @@ public partial record struct PostalAddress
9898
StateAbbreviation state,
9999
string zip)
100100
{
101-
...
101+
this.RecipientFullName = recipientFullName;
102+
this.StreetAddress1 = streetAddress1;
103+
this.StreetAddress2 = streetAddress2;
104+
this.City = city;
105+
this.State = state;
106+
this.Zip = zip;
102107
}
103108

104109
// Decoding constructor.
@@ -137,13 +142,13 @@ struct PostalAddress {
137142
```csharp
138143
public partial record struct PostalAddress
139144
{
140-
public string RecipientFullName;
141-
public string StreetAddress1;
142-
public string? StreetAddress2;
143-
public string? StreetAddress3; // tagged
144-
public string City;
145-
public StateAbbreviation State;
146-
public string Zip;
145+
public required string RecipientFullName { get; set; }
146+
public required string StreetAddress1 { get; set; }
147+
public string? StreetAddress2 { get; set; }
148+
public string? StreetAddress3 { get; set; }
149+
public required string City { get; set; }
150+
public StateAbbreviation State { get; set; }
151+
public required string Zip { get; set; }
147152

148153
// Primary constructor.
149154
public PostalAddress(
@@ -155,7 +160,13 @@ public partial record struct PostalAddress
155160
StateAbbreviation state,
156161
string zip)
157162
{
158-
...
163+
this.RecipientFullName = recipientFullName;
164+
this.StreetAddress1 = streetAddress1;
165+
this.StreetAddress2 = streetAddress2;
166+
this.StreetAddress3 = streetAddress3;
167+
this.City = city;
168+
this.State = state;
169+
this.Zip = zip;
159170
}
160171

161172
// Decoding constructor.
@@ -195,17 +206,16 @@ compact struct Point { x: int32, y: int32 }
195206
```csharp
196207
public readonly partial record struct Point
197208
{
198-
public readonly int X;
199-
200-
public readonly int Y;
209+
public int X { get; init; }
210+
public int Y { get; init; }
201211

202212
...
203213
}
204214
```
205215

206216
{% /aside %}
207217

208-
You can also apply `cs::readonly` to a struct field to map this field to a read-only C# field.
218+
You can also apply `cs::readonly` to a struct field to map this field to a get-init property.
209219

210220
[tagged-fields]: fields#tagged-fields
211221

0 commit comments

Comments
 (0)