来自C++背景,我习惯于将const关键字粘贴到函数定义中,以使对象以只读值传递.但是,我发现在C#中这是不可能的(如果我错了请纠正我).经过一些谷歌搜索后,我得出的结论是,制作只读对象的唯一方法是编写一个只有'get'属性并将其传入的接口.优雅,我必须说.
public interface IFoo
{
IMyValInterface MyVal{ get; }
}
public class Foo : IFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
}
}
Run Code Online (Sandbox Code Playgroud)
我会把它传递给:
public void SomeFunction(IFoo fooVar)
{
// Cannot modify fooVar, Excellent!!
}
Run Code Online (Sandbox Code Playgroud)
这可以.但是,在我的其余代码中,我想正常修改我的对象.向接口添加"set"属性会破坏我的只读限制.我可以添加一个'set'属性Foo(而不是IFoo),但签名需要一个接口而不是一个具体的对象.我不得不做一些铸造.
// Add this to class Foo. Might assign null if cast fails??
set { _myVal = value as ConcreteMyVal; }
// Somewhere else in the code...
IFoo myFoo = new Foo;
(myFoo as Foo).MyFoo = new ConcreteMyVal();
Run Code Online (Sandbox Code Playgroud)
是否有更优雅的方式复制const或制作只读函数参数而不添加其他属性或函数?
我想你可能正在寻找一个涉及两个接口的解决方案,其中一个继承自另一个接口:
public interface IReadableFoo
{
IMyValInterface MyVal { get; }
}
public interface IWritableFoo : IReadableFoo
{
IMyValInterface MyVal { set; }
}
public class Foo : IWritableFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
set { _myVal = value as ConcreteMyVal; }
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以声明参数类型"告诉"它是否计划更改变量的方法:
public void SomeFunction(IReadableFoo fooVar)
{
// Cannot modify fooVar, excellent!
}
public void SomeOtherFunction(IWritableFoo fooVar)
{
// Can modify fooVar, take care!
}
Run Code Online (Sandbox Code Playgroud)
这模仿了类似于C++中的constness的编译时检查.作为埃里克利珀正确地指出,这是不一样的不变性.但作为一名C++程序员,我认为你知道这一点.
顺便说一句,如果在类中声明属性的类型ConcreteMyVal并分别实现接口属性,则可以实现稍微更好的编译时检查:
public class Foo : IWritableFoo
{
private ConcreteMyVal _myVal;
public ConcreteMyVal MyVal
{
get { return _myVal; }
set { _myVal = value; }
}
public IMyValInterface IReadableFoo.MyVal { get { return MyVal; } }
public IMyValInterface IWritableFoo.MyVal
{
// (or use “(ConcreteMyVal)value” if you want it to throw
set { MyVal = value as ConcreteMyVal; }
}
}
Run Code Online (Sandbox Code Playgroud)
这样,setter只能在通过接口访问时抛出,而不能在通过类访问时抛出.
最接近的等价物是in关键字。usingin使参数和输入参数并防止其在方法内部被更改。来自官方 C# 文档:
in- 指定该参数通过引用传递,但只能由被调用的方法读取。ref- 指定该参数通过引用传递,并且可以由被调用的方法读取或写入。out- 指定该参数通过引用传递,并且必须由被调用的方法写入。| 归档时间: |
|
| 查看次数: |
18730 次 |
| 最近记录: |