How can I make properties optionally Read-Only or settable in various related classes?
In my project, I am creating generic interfaces to be used by a number of classes. This includes some properties that must always be present.
Some of the classes will be generic, and therefore the property must be changeable at run-time. Some of the classes will be highly specialized, and therefore, the value of the prope开发者_StackOverflowrty will be hard-coded. I would like to be able to use Bindings in the user interface to display and, where possible, edit the values. Also, I can imagine that at some point, I would want to use reflection to determine if the properly is settable.
What is the best way to accomplish this?
1) Define the properties as read-write in the interface, but have an empty setter in the specialized classes. This appears to be a somewhat common practice, but I am concerned with how binding and reflection would work. A UI control would still appear editable, just that the change by a user would not take, right?
2) Define the properties as read-only in the interface, but provide a setter in the generic classes. I would expect that the UI, bound to use the interface, would still see the property as read-only, and not allow editing.
3) Define the properties as read-only in the interface, but provide some other function to change the value in generic classes. This clearly breaks the property paradigm, and a binding wouldn't know about it to allow editing.
Is there some other way to enable or disable the setters that would be recognized by bindings and reflection?
OK, here my 2 cents - you might not like what I am going to say.
If you have a property that is read-only sometimes and read-write other times and constant in the rest, you are having a leaky abstraction here were polymorphism probably will only result in confusion to the clients of your classes.
So either I would have 2 interfaces one with read-write the other read-only, or just abandon polymorphism for such properties.
You should definitely only have a getter on the properties in your interface. Having a setter that is not always implemented will only lead to confusion.
You can then implement a setter in the appropriate classes. Depending on your application, you might want to create an extended interface that allows for your property to be set.
Example:
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();
}
}
精彩评论