Средствами компилятора вы не можете изменяемый объект превратить в неизменяемый.
Но вы можете это сделать средствами ООП. Например, объявить интерфейс только для чтения
public interface IMyObjectReadonly
{
int A{get;}
int B{get;}
}
public class MyObject : IMyObjectReadonly
{
public int A {get; private set;}
public int B {get; private set;}
public void SetA(int a) => A = a;
public void SetB(int b) => B = b;
}
void Foo(IMyObjectReadonly ob)
{
ob.SetA(10); // Error
}
Вы тут можете возразить, что вообще что никто не мешает ob
кастануть в MyObject
и вызвать что надо, типа ((MyObject)ob).SetA(10);
- и, конечно, кто так делает, будет сам себе злобным буратиной. Но если и от этого надо защищаться, то можно написать враппер, например
public class MyObject
{
public int A {get; private set;}
public int B {get; private set;}
public void SetA(int a) => A = a;
public void SetB(int b) => B = b;
public IMyObjectReadonly AsReadonly() => new MyObjectReadonlyWrapper(this);
private class MyObjectReadonlyWrapper : IMyObjectReadonly
{
private MyObject inner;
public MyObjectReadonlyWrapper(MyObject inner)
{
this.inner = inner;
}
public int A => inner.A;
public int B => inner.B;
}
}
И вызывать метод Foo как то так
var myOb = new MyObject();
Foo(myOb.AsReadonly());
В этом случае никакие касты никуда не помогут. Единственным вариантом достучаться до объекта будет рефлексия - а это уже не просто злобное буратинство, это уже стрельба по ногам :)