C#只能从类内更新的公共字段
我有一个C#类,它的字段需要从类外可见,但只能从类内更改。但是,问题是该字段是通过公共mutator方法更新的,而不是直接(或通过属性)更新的: 换句话说,我希望方法Update()只能从FirstClass中访问 几种可能的解决方案以及我不认同它们的原因:C#只能从类内更新的公共字段,c#,design-patterns,access-modifiers,C#,Design Patterns,Access Modifiers,我有一个C#类,它的字段需要从类外可见,但只能从类内更改。但是,问题是该字段是通过公共mutator方法更新的,而不是直接(或通过属性)更新的: 换句话说,我希望方法Update()只能从FirstClass中访问 几种可能的解决方案以及我不认同它们的原因: 用setter而不是方法更改SecondClass。-不起作用,因为我需要有参数和很多事情要做 将Update()设置为内部而不是公共。-仍然可以从部件内部访问,这还不够好 从第一个类修改第二个类,即将方法Update()移动到第一个类,使
有办法做到这一点吗?一种方法是将名为
UpdateableSecondClass
的子类作为第一类的内部类。
它将继承自SecondClass
,并有一个方法:Update()
您的SecondClass
根本不应该有Update()
方法。你可以继续向世界其他地方展示它:
public SecondClass TheField {get; private set;}
一种方法是使名为
UpdateableSecondClass
的子类成为FirstClass的内部类。
它将继承自SecondClass
,并有一个方法:Update()
您的SecondClass
根本不应该有Update()
方法。你可以继续向世界其他地方展示它:
public SecondClass TheField {get; private set;}
来杯咖啡怎么样
来杯咖啡怎么样
@aquaraga答案的基本实现,但使用接口:
public interface ISecond
{
// some properties
}
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : ISecond
{
// some properties
public void Update(/*parameters*/)
{
// do something
}
}
}
本质上,公开一个公共接口,该接口具有所有可访问的成员,但没有Update
方法。使用一个私有嵌套类,该类具有Update
方法,但调用代码无法访问,并将其作为接口而不是类公开
一些示例用法:
FirstClass myFirst = ...
myFirst.SomeMethod(); //updates ok!
Console.WriteLine(myFirst.TheField.PropertyA); //can access properties of ISecond
myFirst.TheField.Update(); //compiler error!
一点是,您提到使用“某些字段”;作为一个接口,您将不能拥有字段,而是属性。我不确定这是否会破坏你的交易
编辑:您提到了重用第二类
并尽量减少代码重复的意图。一个快速修复方法可能是声明一些抽象
类,一个受保护的更新
方法,使用内部
构造函数(这样其他程序集就不能从中继承),然后用最小的实现公开更新
调用:
public abstract class SecondClassBase : ISecond
{
// some properties
internal SecondClassBase()
{
}
protected void Update(/*parameters*/)
{
// do something
}
}
然后,在您的第一个类中,除了嵌套类之外,没有任何更改:
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : SecondClassBase
{
public new void Update(/*parameters*/)
{
base.Update(/*parameters*/);
}
}
}
仍然有一些代码重复,但您现在需要做的就是复制/粘贴代码;无需为第一类
的每个实现重新声明属性或更新
逻辑。您还可以将新的Update
方法重命名为其他方法,以避免方法隐藏,但我想我会保留您以前的调用签名。是@aquaraga答案的基本实现,但改用接口:
public interface ISecond
{
// some properties
}
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : ISecond
{
// some properties
public void Update(/*parameters*/)
{
// do something
}
}
}
本质上,公开一个公共接口,该接口具有所有可访问的成员,但没有Update
方法。使用一个私有嵌套类,该类具有Update
方法,但调用代码无法访问,并将其作为接口而不是类公开
一些示例用法:
FirstClass myFirst = ...
myFirst.SomeMethod(); //updates ok!
Console.WriteLine(myFirst.TheField.PropertyA); //can access properties of ISecond
myFirst.TheField.Update(); //compiler error!
一点是,您提到使用“某些字段”;作为一个接口,您将不能拥有字段,而是属性。我不确定这是否会破坏你的交易
编辑:您提到了重用第二类
并尽量减少代码重复的意图。一个快速修复方法可能是声明一些抽象
类,一个受保护的更新
方法,使用内部
构造函数(这样其他程序集就不能从中继承),然后用最小的实现公开更新
调用:
public abstract class SecondClassBase : ISecond
{
// some properties
internal SecondClassBase()
{
}
protected void Update(/*parameters*/)
{
// do something
}
}
然后,在您的第一个类中,除了嵌套类之外,没有任何更改:
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : SecondClassBase
{
public new void Update(/*parameters*/)
{
base.Update(/*parameters*/);
}
}
}
仍然有一些代码重复,但您现在需要做的就是复制/粘贴代码;无需为第一类
的每个实现重新声明属性或更新
逻辑。您还可以将新的Update
方法重命名为其他方法,以避免方法隐藏,但我想我会保留与以前相同的调用签名。我认为您可以使用以下模式:
public partial class FirstClass {
partial class ThirdClass: SecondClass {
public void PerformUpdate(/* parameters */) {
base.Update(/* parameters */);
}
}
public void SomeMethod() {
}
public FirstClass() {
}
public SecondClass TheProperty {
get {
return m_TheField;
}
}
ThirdClass m_TheField=new ThirdClass();
}
public partial class SecondClass {
protected void Update(/* parameters */) {
}
public SecondClass() {
}
}
ThirdClass
继承自SecondClass
,但未公开。属性作为类型为SecondClass
的实例公开,但实际上是类型为ThirdClass
的字段
方法SecondClass.Update
仅对派生类公开。您可以将SecondClass
声明为public,而不是嵌套的,但将文件的更新保持为private 我认为您可以使用以下模式:
public partial class FirstClass {
partial class ThirdClass: SecondClass {
public void PerformUpdate(/* parameters */) {
base.Update(/* parameters */);
}
}
public void SomeMethod() {
}
public FirstClass() {
}
public SecondClass TheProperty {
get {
return m_TheField;
}
}
ThirdClass m_TheField=new ThirdClass();
}
public partial class SecondClass {
protected void Update(/* parameters */) {
}
public SecondClass() {
}
}
ThirdClass
继承自SecondClass
,但未公开。属性作为类型为SecondClass
的实例公开,但实际上是类型为ThirdClass
的字段
方法SecondClass.Update
仅对派生类公开。您可以将SecondClass
声明为public,而不是嵌套的,但将文件的更新保持为private 克里斯·辛克莱的回答很好,这只是另一个选择
public sealed class FirstClass : SecondClass
{
public FirstClass()
{
}
public void SomeMethod(int j)
{
base.Update(j);
}
}
public abstract class SecondClass
{
public SecondClass() { }
protected void Update(int i)
{
Console.WriteLine(i.ToString());
}
}
这只是通过FirstClass访问方法的一部分,Chris Sinclair回答很好,这只是另一种选择
public sealed class FirstClass : SecondClass
{
public FirstClass()
{
}
public void SomeMethod(int j)
{
base.Update(j);
}
}
public abstract class SecondClass
{
public SecondClass() { }
protected void Update(int i)
{
Console.WriteLine(i.ToString());
}
}
这只是获取冰毒的一部分