C# 使属性只能由特定方法设置
我在试着做一个化学等式平衡的东西。为此,我创建了一个类元素:C# 使属性只能由特定方法设置,c#,properties,enums,C#,Properties,Enums,我在试着做一个化学等式平衡的东西。为此,我创建了一个类元素: class Element { public elemEnum ElemType {get; set;} public double Amount {get; set;} // How many atoms of this type in the formula } *elemEnum是所有化学元素的枚举 我想为ElemType设置set解析枚举字符串,但由于set只能接受与value相同类型的值,我决定添加一个方法
class Element
{
public elemEnum ElemType {get; set;}
public double Amount {get; set;} // How many atoms of this type in the formula
}
*elemEnum
是所有化学元素的枚举
我想为ElemType
设置set
解析枚举字符串,但由于set
只能接受与value
相同类型的值,我决定添加一个方法:
public void SetElemType(string type)
{
this.ElemType = (elemEnum)Enum.Parse(typeof(elemEnum), type);
}
有没有一个选项可以让
ElemType
属性只能由SetElemType
方法设置,而不必将其设置为private
并添加GetElemType
方法?如前所述,您可以使用private setter
,或者,您可以将readonly
属性与使用字段和方法的public getter
一起使用来修改此字段:
class Element
{
private elemEnum _elemType;
public elemEnum ElemType { get { return _elemType; } }
public void SetElemType(string type)
{
this._elemType = (elemEnum)Enum.Parse(typeof(elemEnum), type);
}
public double Amount {get; } // How many atoms of this type in the formula
}
虽然它实际上与私有setter的属性相同,但它使用的方法略有不同
如果您确实希望只允许一个(!)方法更改值,则可以使用反射并添加封装枚举的类:
class MyElemSetter
{
private readonly elemEnum elem;
public MyElemSetter(elemEnum e, Action helperAction)
{
MethodInfo callingMethodInfo = helperAction.Method;
if (helperAction.Method.Name.Contains("<SetElemType>")) elem = e;
}
public static implicit operator elemEnum(MyElemSetter e)
{
return e.elem;
}
}
class Element
{
private MyElemSetter _elemType;
public elemEnum ElemType { get { return _elemType; } }
public void SetElemType(string type)
{
this._elemType = new MyElemSetter((elemEnum)Enum.Parse(typeof(elemEnum), type), () => { });
}
public double Amount { get; set; } // How many atoms of this type in the formula
}
类MyElemSetter
{
私有只读elemEnum elem;
公共MyElemSetter(elemEnum e,Action helperAction)
{
MethodInfo callingMethodInfo=helperAction.Method;
if(helperAction.Method.Name.Contains(“”)elem=e;
}
公共静态隐式运算符elemEnum(MyLemsetter e)
{
返回e.elem;
}
}
类元素
{
私有MyElemSetter_elemType;
公共elemEnum ElemType{get{return{u ElemType;}}
公共void SetElemType(字符串类型)
{
这个._elemType=newmyelemsetter((elemEnum)Enum.Parse(typeof(elemEnum),type),()=>{});
}
public double Amount{get;set;}//公式中有多少个这种类型的原子
}
不必把它保密
您可以通过向类中添加bool
字段并稍微修改属性来创建一个变通解决方案
class Element
{
private bool _elemCanBeSet = false;
private elemNum _elemType;
public elemEnum ElemType
{
get { return _elemType; }
set { if (_elemCanBeSet) _elemType = value; }
}
public double Amount {get; set;} // How many atoms of this type in the formula
public void SetElemType(string type)
{
_elemCanBeSet = true;
this.ElemType = (elemEnum)Enum.Parse(typeof(elemEnum), type);
_elemCanBeSet = false;
}
}
此解决方案可能会使使用您的类的开发人员感到困惑,因为设置属性将无效。正如其他人所说,在你的任务中使用一个私人的setter是更好的。我只是想展示另一种方法。因为评论中最明显的解决方案并不是作为答案编写的: 使用一个。
这样,
ElemType
只能从您自己的类中设置。C#中有私有的getter/setterpublic elemEnum ElemType{get;private set;}
。您尝试过使用它吗?对于您的问题,我认为不可能使用auto setter/getter方法来接受与变量类型不同的类型。您可以将ElemType的setter设置为private,以确保它只能在类中的表单中设置。可能是主题,但C#中的类型名称应该是pascal大小写,意思是“elemEnum”应该是“elemEnum”好的,也许你可以这样做,这样属性的用途是什么?常见的解决方案是使用私有setter,如Caramiriel的评论所示。您的属性可能仍然由类的其他成员设置,但这不应该成为问题,因为您可以完全控制类的实现。@edost我不知道有私有的set/getter。我对大写的不好,我对这个有点陌生,我将来会注意到。为什么你会喜欢这个而不是现有的语言结构-私有setters?@Rotem这个OP几乎被要求避免现有的语言结构。我认为你的评论应该是对这个问题的评论,而不是对这个答案的评论。我只是想展示一下,如何在不将属性私有化的情况下实现OP想要的东西(参见我文章开头的引文)。@hvd OP问他们如何避免将整个属性私有化(因此必须提供额外的手动getter和setter)。OP不知道私有setter。Lol如果我们添加另一个方法,将\u elemCanBeSet
更改为true
,然后毫无问题地修改值,会怎么样?在这种情况下,这会有什么帮助?我不确定将其设置为私有setter是否是最好的解决方案,如果目标是使一个只能通过该方法设置的pro-party,那么仅将其设置为私有将不起作用。因为该类中的任何方法都可以编辑该值。因此,我认为卡波尔的答案是解决这个问题的更好办法。@EdoPost我怀疑OP是在试图保护它不受自己类的方法的影响,而不是受到外部操纵。@EdoPost是的,Rotem是正确的。除了属性、构造函数和方法之外,这个类可能根本就不会保存任何东西。
class Element
{
public ElemEnum ElemType {get; private set;}
public double Amount {get; set;}
public void SetElemType(string type)
{
this.ElemType = (ElemEnum)Enum.Parse(typeof(ElemEnum), type);
}
}