Did interfaces in C# need evolution? Maybe yes. Are they violating some fundamental principles? We see. Are we asking for some hoops? Let's see all this by telling a story (of code, of course)
Marco ParenzanSenior Solutions Architect @ beanTech, Microsoft MVP
5. Azure IoT Central and IoT PnP
• When you work with IoT Central, you work with IoT PnP
• IoT PnPDigital Twin Definition Language
• InterfaceComponentCapability
• Capability=Telemetry // Property // Command
• When you define a Telemetry, it has
• Semantic
• Unit
• Type
• All described in JSON
• You can do code generation in front of it!
8. C# 1: Value Types and Reference Types
• Reference Type (allocated in heap – referenced in .... Stack...object, polymorphic)
• Value Type (allocated in stack – non polimorphic)
• Struct and Class for custom typesguided by a domain design
• Int, float, double, boolnot guided by a domain
9. «missing type»=scalars!
• Scalar=Primitive=Struct(ural)=sealed[cannot derive]
• You cannot qualify a scalar
• All class goodies (type checking) are (almost) avoided
• Lot of mess:
• Method signs
• Overload collisions
• Custom Types can introduce more meaning
• How?
• Like triggers in SQL, .NET has structs (missing in action)
10. Value Types in .NET
• ...or more simpler, structs in C#
• Remember: the formal definition says «allocated into the stack, not into the heap»
• Be more precise
• Reference typea variable, or a parameter, containes a reference to an entity into the heap
• Value type a variable, or a parameter, containes directly the entity
• Value typecopy semantic
• Reference typereference (obviously) semantics
• Value types are fast
11. C# 3: Extension methods
• Adding methods «externally injected» into objects
• Defined in static methods in static classes, with first argument decorated by «this» keyword
12. C# 8: default interface methods
• Add support for virtual extension methods - methods in interfaces with concrete implementations. A
class or struct that implements such an interface is required to have a single most
specific implementation for the interface method, either implemented by the class or struct, or
inherited from its base classes or interfaces. Virtual extension methods enable an API author to add
methods to an interface in future versions without breaking source or binary compatibility with
existing implementations of that interface.
13. C#11: Static abstract members in interfaces
• An interface is allowed to specify abstract static members that implementing classes and structs are
then required to provide an explicit or implicit implementation of. The members can be accessed off
of type parameters that are constrained by the interface.
14. Parsing Interfaces
Interface name Description
IParsable<TSelf> Exposes support for T.Parse(string, IFormatProvider) and T.TryParse(string,
IFormatProvider, out TSelf).
ISpanParsable<TSelf> Exposes support for T.Parse(ReadOnlySpan<char>,
IFormatProvider) and T.TryParse(ReadOnlySpan<char>, IFormatProvider, out
TSelf).
IFormattable
1
Exposes support for value.ToString(string, IFormatProvider).
ISpanFormattable
1
Exposes support for value.TryFormat(Span<char>, out int,
ReadOnlySpan<char>, IFormatProvider).
15. C# 11: Generic Math
• .NET 7 introduces new math-related generic interfaces to the base class library. The availability of
these interfaces means you can constrain a type parameter of a generic type or method to be
"number-like". In addition, C# 11 and later lets you define static virtual interface members. Because
operators must be declared as static, this new C# feature lets operators be declared in the new
interfaces for number-like types.
• Together, these innovations allow you to perform mathematical operations generically—that is,
without having to know the exact type you're working with. For example, if you wanted to write a
method that adds two numbers, previously you had to add an overload of the method for each type
(for example, static int Add(int first, int second) and static float Add(float first, float second)).
16. Numeric Interfaces
Interface name Description
IBinaryFloatingPointIeee754<TSelf> Exposes APIs common to binary floating-point types
1
that implement the IEEE 754 standard.
IBinaryInteger<TSelf> Exposes APIs common to binary integers
2
.
IBinaryNumber<TSelf> Exposes APIs common to binary numbers.
IFloatingPoint<TSelf> Exposes APIs common to floating-point types.
IFloatingPointIeee754<TSelf> Exposes APIs common to floating-point types that implement the IEEE 754 standard.
INumber<TSelf> Exposes APIs common to comparable number types (effectively the "real" number domain).
INumberBase<TSelf> Exposes APIs common to all number types (effectively the "complex" number domain).
ISignedNumber<TSelf> Exposes APIs common to all signed number types (such as the concept of NegativeOne).
IUnsignedNumber<TSelf> Exposes APIs common to all unsigned number types.
IAdditiveIdentity<TSelf,TResult> Exposes the concept of (x + T.AdditiveIdentity) == x.
IMinMaxValue<TSelf> Exposes the concept of T.MinValue and T.MaxValue.
IMultiplicativeIdentity<TSelf,TResult> Exposes the concept of (x * T.MultiplicativeIdentity) == x.
17. Operator Interfaces
Interface name Defined operators
IAdditionOperators<TSelf,TOther,TResult> x + y
IBitwiseOperators<TSelf,TOther,TResult> x & y, x | y, x ^ y, and ~x
IComparisonOperators<TSelf,TOther,TResult> x < y, x > y, x <= y, and x >= y
IDecrementOperators<TSelf> --x and x--
IDivisionOperators<TSelf,TOther,TResult> x / y
IEqualityOperators<TSelf,TOther,TResult> x == y and x != y
IIncrementOperators<TSelf> ++x and x++
IModulusOperators<TSelf,TOther,TResult> x % y
IMultiplyOperators<TSelf,TOther,TResult> x * y
IShiftOperators<TSelf,TOther,TResult> x << y and x >> y
ISubtractionOperators<TSelf,TOther,TResult> x - y
IUnaryNegationOperators<TSelf,TResult> -x
IUnaryPlusOperators<TSelf,TResult> +x
22. Math with value types
• Another «missing in action»: implicit operator and operator overloading
• Do you remember that you can overload aritmetic operators to use your value types?
• And that you can cast from scalars to structural types (also reference types)?
• Do you know that all of these can become a great math?
24. Let’s remember physics
• Volt+Volt=Volt (you can add or subtract homogeneus values)
• Volt*Ampere=Ampere*Volt=Watt (multiplication is commutative)
• Watt/Ampere != Ampere/Watt (division is not commutative)
• ...and remember the plain good old ToString method!
25. Innovation in JSON Parsing
• Some new features
• Contract customization gives you more control over how types are serialized and deserialized. For more
information, see Customize a JSON contract.
• Polymorphic serialization for user-defined type hierarchies. For more information, see Serialize properties of
derived classes.
• Support for required members, which are properties that must be present in the JSON payload for
deserialization to succeed. For more information, see Required properties.
28. «Scripting» in .NET
• Physics and math is about customizing a job (because you have to «express» some laws)
• You have to express calculations
• A couple of choices:
• CSharp Scripting (Roslyn)
• ANTLR