0

This is specifically referring to some C# properties I want to rewrite.

Example of one of the original properties:

public double? PartQuantity
{
    get
    {
        if( MaintenanceRequestPart != null )
            return MaintenanceRequestPart.ReportedQuantity.HasValue
                ? (double?)MaintenanceRequestPart.ReportedQuantity.Value
                : null;

        return null;
    }
}

What this will be changed to:

public double? PartQuantity => MaintenanceRequestPart?.ReportedQuantity;

note 1: MaintenanceRequestPart can be null

note 2: MaintenanceRequestPart.ReportedQuantity is a nullable double

Will this save or add some operations/branching/overhead? I'm curious as to what the ?. operator actually translates into behind the scenes once it's turned into intermediate language.

Jmaurier
  • 767
  • 2
  • 10
  • 28
  • 1
    Since `ReportedQuantity` is already a nullable double, in the original code, why aren't you simply doing `if( MaintenanceRequestPart != null ) return MaintenanceRequestPart.ReportedQuantity;` – dbc Dec 13 '17 at 19:39
  • 2
    But also see https://ericlippert.com/2012/12/17/performance-rant/. Why not test it yourself? – dbc Dec 13 '17 at 19:46
  • If you want to know what the IL will be for that code, then compile it and look at the IL. You don't need us to compile it for you. – Servy Dec 13 '17 at 19:47
  • `MaintenanceRequestPart.ReportedQuantity.HasValue ? (double?)MaintenanceRequestPart.ReportedQuantity.Value : null` behaves identially to `MaintenanceRequestPart.ReportedQuantity`. The conditional operator there is redundant. – Servy Dec 13 '17 at 19:49
  • 3
    Does https://www.filipekberg.se/2015/01/11/csharp-6-0-null-propagation/ help? – Caius Jard Dec 13 '17 at 19:53

1 Answers1

4

This is perfectly fine. The only difference is that it will copy reference of this variable on IL level. So this is basicaly means that:

public double? PartQuantity => MaintenanceRequestPart?.ReportedQuantity;

Is the same as:

public double? PartQuantity 
{
    get
    {
        var value = MaintenanceRequestPart;
        return value == null ? null : value.ReportedQuantity;
    }
}

Why did it do this additional copying? The answer is pretty simple - to capture value for atomic desicion if this value accessed from different threads. It is very useful when you work with events (so it will not throw NullReferenceException in the middle of "?" operator):

public event EventHandler OnSomethingHappened;
...
OnSomethingHappened?.Invoke(this, new EventArgs());

But, do not fear, it will not have reasonable impact on performance.

Verdict: you can do this refactoring without losing a thing

eocron
  • 6,885
  • 1
  • 21
  • 50
  • 1
    I would be very confident that it would have no performance impact since it's really just a compiler semantic sugar. – Erik Philips Dec 13 '17 at 20:22