Generic type constraints (where clause) in UML
Asked Answered
R

1

6

I have a generic C# class, which looks like this:

public class Database<T>
    where T : class, IModel, new()
{
    //Some code ...
}

T should implement the interface IModel and T have to be a class with an empty constructor.

The question is, how do this look in a UML class diagram.

Thank you.

Rese answered 29/5, 2017 at 14:27 Comment(1)
Possible duplicate of Representing a C# Generic Method in a UML Class DiagramEngland
B
3

In short:

UML uses class templates for this purpose:

UML class template with an ordinary class box, and a small doted box overlapping top right corner in which template paramters are shown

For this to work, you'd have to define somewhere (in a C# profile?) that NewConstraint is a special interface that requires the implementing class to have a parameterless constructor. Alternatively, you could skip this the NewConstraint and add a simple UML constraint (e.g. a note with the constraint in plaintext { T shall have a parameterless constructor } )

Some more explanations about template parameters

More on the syntax of UML classifier template can be found in the UML specs (page 103):

A ClassifierTemplateParameter extends the notation for a TemplateParameter to include an optional type constraint:

<classifier-template-parameter> ::=
<parameter-name> [ ‘:‘ <parameter-kind> ] [‘>’ <constraint>]
[‘=’ <default>]
<constraint> ::= [‘{contract }’] <classifier-name>*

The parameter-kind indicates the metaclass of the parameteredElement. It may be suppressed if it is ‘Class.’

The classifier-name of constraint designates a constrainingClassifier, of which there may be zero or more, with the meaning specified in the semantics above. The ‘contract’ option indicates that allowSubstitutable is true.

Since I misunderstood the {contract} myself, and first confused it with an ordinary constraint, let's clarify this important hint:

  • {contract} xxx means that the parameter allows the substitution of the parameter with a classifier having the same contract than xxx. This is needed when a paramter is a class that is constrained by specific interfaces.
  • xxx (without {contract}) means that the parameter is required to be xxx or a specialization of it. In consequence, this cannot be used for a class that has to implement an interface, since the class is an implementation of an interface and not a specialization.

In your case, the parameter would then be:

T : class > {contract} IModel NewConstraint

But since class is the parameter-kind by default, it could be simplified to:

T > {contract} IModel NewConstraint
Bowden answered 10/7, 2021 at 21:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.