Константный объект С#
void test(in A a) {
a.modify(); // Не константный метод. Вызови ошибку! Нет...
}
A a = new A(1, 2);
test(a);
Console.WriteLine($"a.a: {a.a}");
public class A {
public int a;
public int b;
public A(int a, int b) { this.a = a; this.b = b; } // можно красивее, но пока не умею )
public void modify() => a = b;
}
Как мне защитить себя от вызова для константного объекта неконстантного метода?
Ответы (1 шт):
Средствами компилятора вы не можете изменяемый объект превратить в неизменяемый.
Но вы можете это сделать средствами ООП. Например, объявить интерфейс только для чтения
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());
В этом случае никакие касты никуда не помогут. Единственным вариантом достучаться до объекта будет рефлексия - а это уже не просто злобное буратинство, это уже стрельба по ногам :)