Skip to content

How to Resolve Error "CS0445: Cannot modify the result of an unboxing conversion" in C#

Learn how to fix C# compiler error CS0445 when working with boxed structs, including proper unboxing techniques and interface-based modification methods.

The Compiler Error CS0445 is a logical safety error related to Structs (Value Types) and Boxing. The message reads: "Cannot modify the result of an unboxing conversion".

In C#, when you store a Value Type (like a struct or int) inside a Reference Type variable (like object or an interface), it is called Boxing. When you cast it back to the struct type, it is called Unboxing.

Unboxing produces a temporary copy of the value. If you attempt to modify a field or property directly on that unboxed result in a single statement (e.g., ((Point)obj).X = 10;), you would be modifying the temporary copy, not the original object stored in the heap. The compiler prevents this because the change would be discarded immediately, creating a logic bug.

This guide explains how to correctly modify boxed value types.

Understanding Unboxing and Copies

  • Reference Types: If you cast an object (MyClass)obj, you get a reference to the same object. Modifying it updates the original.
  • Value Types (Unboxing): If you cast (MyStruct)obj, the runtime extracts the value from the box and places a new copy on the stack.

If you write: ((MyStruct)obj).Value = 5;

  1. The runtime unboxes obj to a temp copy.
  2. You set Value to 5 on the temp copy.
  3. The statement ends. The temp copy is discarded.
  4. obj remains unchanged.

The compiler raises CS0445 to tell you: "You are trying to write to a temporary variable that vanishes instantly. This is surely not what you intended."

Scenario: Modifying a Casted Object

This error occurs frequently when using mutable structs (structs with public fields or setters) stored in generic object collections or loosely typed variables.

Example of error:

public struct Point
{
    public int X;
    public int Y;
}

public class Program
{
    static void Main()
    {
        // 1. Box the struct into an object
        object obj = new Point { X = 10, Y = 10 };

        // ⛔️ Error CS0445: Cannot modify the result of an unboxing conversion
        // (Point)obj creates a temporary Point. We try to set X on that temp.
        ((Point)obj).X = 20; 
    }
}

Solution 1: Unbox, Modify, Rebox (Standard Fix)

To modify the data, you must explicitly accept that you are working with copies.

  1. Unbox the data into a local variable.
  2. Modify the local variable.
  3. Assign the local variable back to the storage location (re-boxing it).

Solution:

public class Program
{
    static void Main()
    {
        object obj = new Point { X = 10, Y = 10 };

        // 1. Unbox to a local variable (This creates a copy on the stack)
        Point p = (Point)obj;

        // 2. Modify the local variable
        p.X = 20;

        // 3. Assign it back (Re-boxes the modified value)
        obj = p;

        // Verify the change
        Console.WriteLine(((Point)obj).X); 
    }
}

Output:

20

Solution 2: Mutating via Interface (Advanced)

There is a subtle way to modify a boxed struct in-place without unboxing it fully to the stack: using an Interface.

When you cast a boxed struct to an interface it implements, you receive a reference to the boxed object on the heap, not a copy. Modifying the interface modifies the boxed value directly.

Solution:

// Define an interface for the mutation
public interface IPoint
{
    int X { get; set; }
}

// Implement it in the struct
public struct Point : IPoint
{
    public int X { get; set; }
    public int Y { get; set; }
}

public class Program
{
    static void Main()
    {
        object obj = new Point { X = 10, Y = 10 };

        // ✅ Correct: Cast to the Interface.
        // This returns a reference to the boxed object, not a copy.
        ((IPoint)obj).X = 20;

        Console.WriteLine(((Point)obj).X); 
    }
}

Output:

20

Conclusion

CS0445 prevents "silent failures" where you modify a disposable copy of your data.

  1. Understand Structs: Remember that casting (Struct)Object creates a copy.
  2. Use Local Variables: Extract the struct to a variable var temp = (Struct)obj;, modify temp, and save it back.
  3. Avoid Mutable Structs: If possible, design structs to be Immutable (readonly). This forces you to overwrite the whole object anyway (obj = new Point(20, 10)), avoiding this confusion entirely.
Navigation