I noticed that assigning a new instance of ObjectAttributes to an existing RhinoObject will give the object an ID of Guid.Empty, after which any changes are no longer propagated. On the other hand, changing values the existing instance of ObjectAttributes on the object does work.
To reproduce, open a default document (in which there is Layer 03) and draw two objects on the Default Layer. Then run the command below, selecting first the one object, the the other. The first object will not be moved to Layer 03, whereas the other will be moved to layer 03.
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
ObjRef gRef;
Result r = RhinoGet.GetOneObject("Select an object", false, ObjectType.AnyObject, out gRef);
if (r != Result.Success) return r;
int layerIndex = doc.Layers.Find("Layer 03", true);
ObjectAttributes attr = new ObjectAttributes { LayerIndex = layerIndex, Name = "Attributes replaced" };
Guid id = gRef.ObjectId;
RhinoObject obj = doc.Objects.Find(id);
obj.Attributes = attr;
RhinoApp.WriteLine("obj.ID"+obj.Id); // replacing the Attributes sets Id to Guid.Empty
obj.CommitChanges(); // has no effect
doc.Objects.UnselectAll(true);
doc.Views.Redraw();
r = RhinoGet.GetOneObject("Select another object", false, ObjectType.AnyObject, out gRef);
if (r != Result.Success) return r;
id = gRef.ObjectId;
obj = doc.Objects.Find(id);
obj.Attributes.LayerIndex = layerIndex; // assigning attributes is OK
obj.Attributes.Name = "Attributes changed";
RhinoApp.WriteLine("obj.ID" + obj.Id);
obj.CommitChanges();
return Result.Success;
}