C# 如何使属性在各种相关类中可选为只读或可设置?
在我的项目中,我正在创建一些类要使用的通用接口。这包括一些必须始终存在的属性 有些类是泛型的,因此属性在运行时必须是可变的。有些类将是高度专业化的,因此,属性的值将是硬编码的。我希望能够在用户界面中使用绑定来显示并在可能的情况下编辑值。此外,我可以想象,在某个时刻,我想使用反射来确定是否可以正确设置 实现这一目标的最佳方式是什么 1) 在接口中将属性定义为读写,但在专用类中有一个空的setter。这似乎是一种比较常见的做法,但我关心的是约束和反射如何工作。UI控件仍然会显示为可编辑,只是用户所做的更改不会接受,对吗 2) 在接口中将属性定义为只读,但在泛型类中提供setter。我希望绑定使用该接口的UI仍然将该属性视为只读,并且不允许编辑 3) 在接口中将属性定义为只读,但提供一些其他函数来更改泛型类中的值。这显然打破了属性范式,绑定不知道如何进行编辑C# 如何使属性在各种相关类中可选为只读或可设置?,c#,properties,C#,Properties,在我的项目中,我正在创建一些类要使用的通用接口。这包括一些必须始终存在的属性 有些类是泛型的,因此属性在运行时必须是可变的。有些类将是高度专业化的,因此,属性的值将是硬编码的。我希望能够在用户界面中使用绑定来显示并在可能的情况下编辑值。此外,我可以想象,在某个时刻,我想使用反射来确定是否可以正确设置 实现这一目标的最佳方式是什么 1) 在接口中将属性定义为读写,但在专用类中有一个空的setter。这似乎是一种比较常见的做法,但我关心的是约束和反射如何工作。UI控件仍然会显示为可编辑,只是用户所做
是否有其他方法来启用或禁用绑定和反射可以识别的setter?您的接口中的属性应该只有getter。拥有一个不总是实现的setter只会导致混乱 然后可以在适当的类中实现setter。根据应用程序的不同,您可能希望创建一个允许设置属性的扩展接口 例如:
public interface ITest
{
int Test { get; }
}
public interface ITestExtended : ITest
{
new int Test { get; set; }
}
public class Monkey : ITestExtended
{
public int Test { get; set; }
// Be carefull to explicitly implement the original interface
int ITest.Test
{
get
{
return 7;
}
}
}
public class MonkeySimple : ITest
{
public int Test
{
get { return 10; }
}
}
class Program
{
static void Main(string[] args)
{
ITestExtended monkey = new Monkey() { Test = 5 };
ITest monkeySimple = monkey;
Console.WriteLine(monkeySimple.Test);
Console.WriteLine(monkey.Test);
// Compiler error
//monkeySimple.Test = 6;
Console.ReadKey();
}
}
好的,这是我的2美分——你可能不喜欢我要说的话 如果您有一个属性有时是只读的,有时是读写的,其余时间是常量,那么您就有了一个泄漏的抽象
因此,或者我会有两个接口,一个是读写接口,另一个是只读接口,或者只是放弃这些属性的多态性 实际上,我同意这里漏洞百出的抽象,这就是我提出这个问题的原因。我会让IMyInterface具有只读属性,IMyEditableInterface具有与读写相同的属性,然后在需要的地方实现IMyEditableInterface吗?对于UI,我可能需要为这两个版本使用不同的控件,但这可能没有那么糟糕……如果不知道域的细节,很难说。关键不在于使用哪种抽象,而在于使用最能代表您的模型的抽象。我想说,如果两个接口都能工作,那么就使用它。事实上,一个接口只能包含write-only,因此如果一个对象同时实现了这两个接口,那么它就是读写的……进一步考虑,只读用例和读写用例是不同的。属性始终用于计算;在某些类别中,这将是固定的或基于其他属性计算的。在读写情况下,用于支持其他情况,其中该值为常量,用于计算,但用户可能会更改。因此,现在有一个用于计算的标准接口(包括只读属性)和一个支持用户更改的高度可变的接口是有意义的。在这个简单的例子中,这两个属性可以共享一个支持字段。注意:这个答案和来自Aliostad的答案非常相似。我选择这个作为答案有两个原因:1)它更简洁,2)它建议使用扩展接口。我最初接受了这个答案,但经过改进,我发现了一些问题。也许其他语言有所不同,但至少在C语言中,似乎不能将setter添加到现有的只读属性中。在子类上扩展它会导致多态性问题,因为我必须定义一个新的getter,并且不能重写父类中的getter;在某些情况下,我想。如果我使用对象作为父类型,则调用父类代码上的getter,而不是子类上的getter。这可能非常危险!仅供参考,我仍然认为这是一个有用的答案,我从探索中学到了很多。主要是,我没有意识到接口可以继承并且是多态的-这是难以置信的强大(即使在.NET框架中这是显而易见的)。但是,在C#中,如果不隐藏原始属性,则无法将只读属性扩展为读写,这会导致问题。