in packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts [923:1012]
private emitProperty(
cls: spec.Type,
prop: spec.Property,
definingType: spec.Type,
datatype = false,
proxy = false,
): void {
this.emitNewLineIfNecessary();
const className = this.typeresolver.toNativeFqn(cls.fqn);
const access = this.renderAccessLevel(prop);
const staticKeyWord = prop.static ? 'static ' : '';
const propName = this.nameutils.convertPropertyName(prop.name);
this.dotnetDocGenerator.emitDocs(prop, {
api: 'member',
fqn: definingType.fqn,
memberName: prop.name,
});
if (prop.optional) {
this.code.line('[JsiiOptional]');
}
this.dotnetRuntimeGenerator.emitAttributesForProperty(prop, datatype);
let isOverrideKeyWord = '';
let isVirtualKeyWord = '';
let isAbstractKeyword = '';
// If the prop parent is a class
if (spec.isClassType(cls)) {
const implementedInBase = this.isMemberDefinedOnAncestor(
cls as spec.ClassType,
prop,
);
if (implementedInBase || datatype || proxy) {
// Override if the property is in a datatype or proxy class or declared in a parent class. If the member is
// static, use the "new" keyword instead, to indicate we are intentionally hiding the ancestor declaration (as
// C# does not inherit statics, they can be hidden but not overridden).The "new" keyword is optional in this
// context, but helps clarify intention.
isOverrideKeyWord = prop.static ? 'new ' : 'override ';
} else if (prop.abstract) {
// Abstract members get decorated as such
isAbstractKeyword = 'abstract ';
} else if (!prop.static && !implementedInBase) {
// Virtual if the prop is not static, and is not implemented in base member, this way we can later override it.
isVirtualKeyWord = 'virtual ';
}
}
const propTypeFQN = this.typeresolver.toDotNetType(prop.type);
const isOptional = prop.optional ? '?' : '';
const statement = `${access} ${isAbstractKeyword}${isVirtualKeyWord}${staticKeyWord}${isOverrideKeyWord}${propTypeFQN}${isOptional} ${propName}`;
this.code.openBlock(statement);
// Emit getters
if (datatype || prop.const || prop.abstract) {
this.code.line('get;');
} else {
// If the property is non-optional, add a bang to silence compiler warning
const bang = prop.optional ? '' : '!';
if (prop.static) {
this.code.line(
`get => GetStaticProperty<${propTypeFQN}${isOptional}>(typeof(${className}))${bang};`,
);
} else {
this.code.line(
`get => GetInstanceProperty<${propTypeFQN}${isOptional}>()${bang};`,
);
}
}
// Emit setters
if (datatype || (!prop.immutable && prop.abstract)) {
this.code.line('set;');
} else {
if (!prop.immutable) {
if (prop.static) {
this.code.line(
`set => SetStaticProperty(typeof(${className}), value);`,
);
} else {
this.code.line('set => SetInstanceProperty(value);');
}
}
}
this.code.closeBlock();
this.flagFirstMemberWritten(true);
}