C# 如何使属性在各种相关类中可选为只读或可设置?

C# 如何使属性在各种相关类中可选为只读或可设置?,c#,properties,C#,Properties,在我的项目中,我正在创建一些类要使用的通用接口。这包括一些必须始终存在的属性 有些类是泛型的,因此属性在运行时必须是可变的。有些类将是高度专业化的,因此,属性的值将是硬编码的。我希望能够在用户界面中使用绑定来显示并在可能的情况下编辑值。此外,我可以想象,在某个时刻,我想使用反射来确定是否可以正确设置 实现这一目标的最佳方式是什么 1) 在接口中将属性定义为读写,但在专用类中有一个空的setter。这似乎是一种比较常见的做法,但我关心的是约束和反射如何工作。UI控件仍然会显示为可编辑,只是用户所做

在我的项目中,我正在创建一些类要使用的通用接口。这包括一些必须始终存在的属性

有些类是泛型的,因此属性在运行时必须是可变的。有些类将是高度专业化的,因此,属性的值将是硬编码的。我希望能够在用户界面中使用绑定来显示并在可能的情况下编辑值。此外,我可以想象,在某个时刻,我想使用反射来确定是否可以正确设置

实现这一目标的最佳方式是什么

1) 在接口中将属性定义为读写,但在专用类中有一个空的setter。这似乎是一种比较常见的做法,但我关心的是约束和反射如何工作。UI控件仍然会显示为可编辑,只是用户所做的更改不会接受,对吗

2) 在接口中将属性定义为只读,但在泛型类中提供setter。我希望绑定使用该接口的UI仍然将该属性视为只读,并且不允许编辑

3) 在接口中将属性定义为只读,但提供一些其他函数来更改泛型类中的值。这显然打破了属性范式,绑定不知道如何进行编辑


是否有其他方法来启用或禁用绑定和反射可以识别的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#中,如果不隐藏原始属性,则无法将只读属性扩展为读写,这会导致问题。