CA2246: Do not assign a symbol and its member in the same statement

Property Value
Rule ID CA2246
Title Do not assign a symbol and its member in the same statement
Category Usage
Fix is breaking or non-breaking Non-breaking
Enabled by default in .NET 8 As suggestion

Cause

A symbol and its member were assigned in the same statement. For example:

// 'a' and 'a.Field' are assigned in the same statement
a.Field = a = b;

Rule description

Assigning a symbol and its member, that is, a field or a property, in the same statement is not recommended. It is not clear if the member access was intended to use the symbol's old value prior to the assignment or the new value from the assignment in this statement. For clarity, the multi-assign statement must be split into two or more simple assignment statements.

How to fix violations

To fix violations, split the multi-assign statement into two or more simple assignment statements. For example, the following code snippet shows a violation of the rule and a couple of ways to fix it based on the user intent:

public class C
{
    public C Field;
}

public class Test
{
    public void M(C a, C b)
    {
        // Let us assume 'a' points to 'Instance1' and 'b' points to 'Instance2' at the start of the method.
        // It is not clear if the user intent in the below statement is to assign to 'Instance1.Field' or 'Instance2.Field'.
        // CA2246: Symbol 'a' and its member 'Field' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
        a.Field = a = b;
    }
}
public class C
{
    public C Field;
}

public class Test
{
    public void M(C a, C b)
    {
        // Let us assume 'a' points to 'Instance1' and 'b' points to 'Instance2' at the start of the method.
        // 'Instance1.Field' is intended to be assigned.
        var instance1 = a;
        a = b;
        instance1.Field = a;
    }
}
public class C
{
    public C Field;
}

public class Test
{
    public void M(C a, C b)
    {
        // Let us assume 'a' points to 'Instance1' and 'b' points to 'Instance2' at the start of the method.
        // 'Instance2.Field' is intended to be assigned.
        a = b;
        b.Field = a; // or 'a.Field = a;'
    }
}

When to suppress warnings

Do not suppress violations from this rule.

See also