Reflection, dynamic. How to replace one object with another? - c#

I have an object like this
public class Simple
{
public string Value
{
get { return GetProperty(); }
}
// different methods, fields, events, etc.
}
Possible to replace instance of the class Simple with equal object, but with setter?
How to implement ...
private object Substitution(object simple)
{
object newSimple;
// implementations
newSimple.Value = "data";
return newSimple;
}
To have something like this
public class Simple
{
public string Value { get; set; }
// my methods, fields, events ...
}
I thought to create a class and inherit from SystemObject, then you can create different dynamic properties, but could not do :(
Or maybe try to inherit from this object (how?) and override the properties?
Thanks

You can't change the definition or structure of a loaded type at runtime.
You could, potentially, make a new type that had a similar set of properties and fields, with the property setter added. However, this is going to be of limited use in most cases, as the existing code will not understand the new type (since it's runtime generated), so would still be working off the existing type, which won't be compatible.
Typically, if you need runtime extensibility within a type, there are other options, including using a Dictionary<T,U>, or dynamic with ExpandoObject, or some other mechanism for storing "extra" information within a class that is not known at compile time.

You couuld always use an interface, that only defines a property getter. Then in the implementation have a property setter?
class Program
{
static void Main(string[] args)
{
IMyClass myA = new ClassA{ Property = "Class A" };
Console.WriteLine(myA.Property);
// can't do this
// myA.Property = "New Property";
// can do this
(myA as ClassA).Property = "New Property";
Console.WriteLine(myA.Property);
}
}
interface IMyClass
{
string Property { get; }
}
class ClassA : IMyClass
{
public string Property { get; set; }
}
Failing that, you could do an user defined conversion using the explicit keyword, more info at MSDN

Related

How to add Classes with inheritance to a Dictionary in C# [duplicate]

This question already has answers here:
C#, access child properties from parent reference?
(5 answers)
Closed 4 years ago.
I am a bit confused about adding classes to a collection. In this case a Dictionary.
I got liked to a "similar" thread.. but it appears to be a totally diff rent issue. My question is about putting multiple classes in a dictionary that are inherited form a common base class. The linked thread is about storing different types like int, string, double.. etc.
class ClassName
{
public string name { get; }
public ClassName()
{
name = "name";
}
}
class Unique : ClassName
{
public string uName { get; }
public Unique()
{
uName = "UniqueName?";
}
}
class YAunique : ClassName
{
public string yaName { get; }
public YAunique()
{
yaName = "YetAnotherName";
}
}
class Program
{
static void Main(string[] args)
{
Dictionary<string, ClassName> doesThisWork = new Dictionary<string, ClassName>();
doesThisWork.Add("test", new Unique());
doesThisWork.Add("test2", new YAunique());
Console.WriteLine(doesThisWork["test"].name);
Console.WriteLine(doesThisWork["test"].uName); //dose not work
Console.WriteLine(doesThisWork["test2"].name);
Console.WriteLine(doesThisWork["test2"].yaName); //does not work
Unique example = new Unique();
Console.WriteLine(example.name);
Console.WriteLine(example.uName);
YAunique example2 = new YAunique();
Console.WriteLine(example2.name);
Console.WriteLine(example2.yaName);
// Pauses the console window
Pause4Input();
}
Basically in the example above I have 3 classes, 2 of which are inherited off the same class. If I initialise either of the inherited classes I can access both the base class's variable and the child class variable (the prints at the bottom of the code)....
....but what I am trying to do is place those child classes in a dictionary.
The thing is even though it "looks" kinda right... I can only access the variables in the base class using the dictionary keys.
TL;DR I am trying to work out how to have different classes added to a dictionary collection and have all the child class functions and variables and the base class functions and variables accessible.
Thanks!
Well, it looks like you got the basics of "Inheritance" but you seem to be having some trouble about what is going to be accessible to base class and what is to derived class. So you have a Dictionary<string, BaseClass>. When you access the value in this dictionary it will be type of BaseClass. Of course it may be of the any type which derives from BaseClass as well. However, unless you cast your value to the correct type you cannot access the derived types properties, methods, etc. You should be careful on how you cast though. Please consider Pattern Matching (Starting from c#7.0)
// value is BaseClass, only methods, properties of BaseClass usable .
var value = dict["myKey"];
// Now derived classes properties etc can be accessed.
var casted = (Derived)value;
You may try leveraging polymorphism.Instead of having different "Names" properties in each derived classes, define a common property (or common properties) in base class and override them in derived classes.
using System;
using System.Collections.Generic;
abstract class ClassName {
public abstract string Name {get;}
}
class Unique : ClassName
{
public override string Name {
get{return "UniqueName?";}
}
public Unique()
{
}
}
class YAunique : ClassName
{
public override string Name {
get{return "YetAnotherName";}
}
public YAunique()
{
}
}
public class Program
{
public static void Main()
{
Dictionary<string, ClassName> doesThisWork = new Dictionary<string, ClassName>();
doesThisWork.Add("test", new Unique());
doesThisWork.Add("test2", new YAunique());
Console.WriteLine(doesThisWork["test"].Name);
Console.WriteLine(doesThisWork["test2"].Name);
}
}

How to redefine a property in C# through interface inheritance?

I have an interface 'IBase' that specifies a nullable int. A later interface 'IDerived' hides the nullable int and 'redefines' it as non-nullable.
interface IBase
{
int? Redefineable { get; set; }
}
interface IDerived : IBase
{
new int Redefineable { get; set; }
}
The class that implements these interfaces must explicitly implement the hidden property, however it's private so the client can't see it.
class TheClass : IDerived
{
public int Redefineable { get; set; }
int? IBase.Redefineable { get; set; }
}
However, even though it's a private property, I can still access it through the IBase interface!
var o = new TheClass();
o.Redefineable = 1; // ok
var hack = o as IBase;
hack.Redefineable = null; // uh!
This seems like some kind of violation of C# access modifiers, but either way it isn't really what I had in mind for redefining (not just hiding) a property. It's correct in the sense that it does what you're asking, get an IBase interface which has a nullable int but this is non-intuitive to the client who could then modify the wrong version of the property.
What I really want, is that if the client accesses IBase.Redefinable, then it behaves as if it's accessing the IDerived.Redefinable property, the 'real' property of TheClass. That way it's actually redefined, as in back through the hierarchy.
class TheClass : IDerived
{
public int Redefineable { get; set; }
int? IBase.Redefineable {
get {
// redirect to redefined property
return this.Redefineable;
}
set
{
// stop client setting it to null
if (!value.HasValue)
throw new InvalidOperationException();
// redirect to redefined property
this.Redefineable = value.Value;
}
}
}
This just feels like a hack, almost as if I'm missing something, so I want to ask if anyone knows a better/alternative way to implement re-definable properties?
However, even though it's a private property, I can still access it through the IBase interface!
It's not a private property. It's just a property using explicit interface implementation. That means it's public through the interface, but only available through the interface. Explicit interface implementation is mostly designed to make it feasible to implement "contradictory" interfaces, as well as being used to "discourage" (but not prohibit) the use of some interface methods. It's not meant to give the impression that the members don't exist at all.
Fundamentally, it sounds like you shouldn't be using inheritance here - if you don't want something to be able to act as an IBase, you shouldn't inherit from IBase.

How Can an Attribute Class Reference the Instance that Uses It?

Let's say I have an attribute class:
public class MyCustomAttribute : Attribute
{
// do stuff
}
And I use this attribute on class properties:
public class MyModel : BaseModel
{
[MyCustom]
public string Name { get; set; }
}
Is there a way, within the code of MyCustomAttribute, to reference the instance of MyModel on which it's being used?
Ultimately I'm just experimenting with AOP (using PostSharp) to create attributes to track when a model is dirty. So if BaseModel has an IsDirty property then I'd like to be able to do something like this with PostSharp:
public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
public override void OnSuccess(MethodExecutionArgs args)
{
someReferenceToTheObject.IsDirty = true;
}
}
I've tried passing a reference into the attribute's constructor:
public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
private BaseModel _currentObject { get; set; }
public TrackDirtyPropertyAttribute(BaseModel currentObject)
{
_currentObject = currentObject;
}
public override void OnSuccess(MethodExecutionArgs args)
{
_currentObject.IsDirty = true;
}
}
However, when I use it:
[TrackDirtyProperty(this)]
public string Name { get; set; }
It tells me that this is not available in that context.
You should do it like this:
public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
public override void OnSuccess(MethodExecutionArgs args)
{
((BaseModel) args.Instance).IsDirty = true;
}
}
Your constructor won't work (at least not with this) because the attribute constructor arguments must be accessible in a static context. And by default you can't simply access the utilising type's instance - which makes sense, since this is essentially metadata (applied to the definition, not instances - the instances just come 'strapped' with it). So you can natively access the attributes of a type, but not the instances of the type used by an attribute.
You could probably get it through some contrived reflection and so forth (I'm not even going to venture into thinking about this), however, not so elegantly one way as the other.
On another note, it makes little sense to me to store the state of an element within an attribute - this isn't persistent enough. Making calculations to retrieve a value (say you did get a hold of the instance, and managed to run some logic to determine if it 'is dirty' and provide a 'real time' value in that sense) yes, but using it to persist information applied to it after the fact of declaration seems futile, since which instance of the attribute is it to persist in anyway? In any case, and regardless of what I might have totally missed in saying this, this is what the instances themselves are for.

How to write a method that can be shared by two non-inherited class

I am having 2 classes, both having a same method(name + type +behavior) and a same property (name + type)
public class Country
{
public string Name { get; set; }
public void DisplayName()
{
Console.WriteLine(this.Name);
}
}
public class Person
{
public string Name { get; set; }
public void DisplayName()
{
Console.WriteLine(this.Name);
}
}
-- Person and Country classes are not allowed to inherit
In the above code you can see Person class has similar method(DisplayName) like Country class. I am looking for a way so that both classes can share the same method codes, i want to do this because in my real codes- Method which i want to share is very big and whenever i change code in one class i have to copy paste it in other class too. That i feel is not the correct way.
Please suggest how to resolve this problem.
You say they cannot inherit from a common base class, but you could add an interface, right? I suggest giving them each a common interface. Then define an extension method for that interface. The method will appear for each of them in VS.
(Assumption: this will work if the class members accessed by the extension methods are public or internal.)
interface IDisplayable
{
string Name {get; set;}
}
public class Country : IDisplayable
{
public string Name { get; set; }
}
public class Person : IDisplayable
{
public string Name { get; set; }
}
public static void DisplayName(this iDisplayable d)
{
return doSomeDisplayLogic(d.Name);
}
. . . And in the same class as your extension method, define (not as an extension method) a function doSomeDisplayLogic to do your common logic. (first-time gotcha: make sure the extension method is in the same Namespace or the its namespace is also included in the calling code.)
I don't know if you're new to extension methods or not. They are very powerful. (And like many powerful features, they can be abused). An extension method on an interface seems crazy at first, until you get straight in your head how extension methods really work. LINQ wouldn't work without this!
Update: I see your comment above that the classes can't inherit from a common class, because they are already inheriting from a common class (which I assume can't be messed with too much). I would like to point out an Option 2, based on this: Creating a new class that Country/Person/etc. will inherit from, that itself inherits from the existing common parent class. The existing base class would become a grandparent class, so to speak. This would become more the route to go if Country and Person have other common characteristics besides this DisplayName method. If DisplayName is all you're after, the Interface/Extension pattern might be better.
Define an interface
public interface INameable
{
string Name {get;}
}
then add an extension
public static class INameableExt
{
public static void DisplayName(this INameable n)
{
// do your thing
}
}
I would suggest to avoid Extension Methods in some cases, you can ran into a problem when you need slightly a different implementation for both classes and then you have to design a more generic solution, EM can cause the same issues like multiple inheritance does.
As more generic OOD solution I would suggest to extract this behaviour into a separate service class abstracted by an interface:
public interface IDisplayService()
{
void Display();
}
Then implement it and inject into both classes via constructor.
Also, instead of introducing the interfaces and new classes you can inject Action or Func<> via constructor or even property and then call this method by invoking an injected in delegate.
You could create either a static utility method DisplayName() that you pass the data needed for display, or use composition and move all properties and corresponding methods such as DisplayName() in a separate class - then use an instance of this class from both Country and Person.
You could implement a strategy pattern:
class DisplayNameStrategy<T> {
private readonly Func<T, string> nameSelector;
public void DisplayNameStrategy(Func<T, string> nameSelector) {
this.nameSelector = nameSelector;
}
public void abstract DisplayName(T t);
}
class WriteToConsoleDisplayNameStrategy<T> : DisplayNameStrategy<T> {
public void WriteToConsoleDisplayNameStrategy(Func<T, string> nameSelector)
: base(nameSelector) { }
public override void DisplayName(T t) {
Console.WriteLine(this.nameSelector(t));
}
public class Person {
private readonly DisplayNameStrategy<Person> displayNameStrategy =
new WriteToConsoleDisplayNameStrategy<Person>(x => x.Name);
public string Name { get; set; }
public void DisplayName() {
this.displayNameStrategy(this);
}
}
Note: it's probably better to inject the concrete strategy.
You could use composition: define an interface, a class that implements it, and then have Person and Country implement the interface by calling methods on the implementation class:
// the interface
public interface IName {
string Name { get; set; }
void DisplayName();
}
// a class that implements the interface with actual code
public class NameImpl : IName {
public string Name { get; set; }
public void DisplayName() {
Console.WriteLine(this.Name);
}
}
public class Country : IName {
// instance of the class that actually implements the interface
IName iname = new NameImpl();
// forward calls to implementation
public string Name {
get { return iname.Name; }
set { iname.Name = value; }
}
public void DisplayName() {
// forward calls to implementation
iname.DisplayName();
}
}
What I THINK you are asking for is multiple class inheritance which is not allowed in C#. (but can be with C++ which you are NOT doing).
All the others have identified doing an INTERFACE solution, and probably the best way to go. However, from your description, you have a SINGLE BLOCK of code that is identical regardless of the type of object being a person or a business. And your reference to a huge block of code, you don't want to copy/paste that same exact code among all the other classes that may be intended to use similar common "thing" to be done.
For simple example, you have a functionality that builds out a person's name and address (or business name and address). You have code that is expecting a name and up to 3 address lines, plus a city, state, zip code (or whatever else). So, the formatting of such name/address information is the same for a person vs a business. You don't want to copy this exact method over and over between the two. However, each individual class still has its own things that it is responsible for.
I know its a simple example for context, but I think gets the point across.
The problem with just defining an Interface is that it won't allow you to actually implement the CODE you are referring to.
From your sample, I would consider doing a combination of things.. Create a static class with methods on it that you might want as "globally" available. Allow a parameter to be passed into it of an instance of a class that has a type of interface all the others have expressed that will guarantee the incoming object has all the "pieces" of properties / methods you are expecting, and have IT operate on it as needed. Something like
public interface ITheyHaveInCommon
{
string Name;
string GetOtherValue();
int SomethingElse;
}
public class Person : ITheyHaveInCommon
{
// rest of your delcarations for the required contract elements
// of the ITheyHaveInCommon interface...
}
public class Country : ITheyHaveInCommon
{
// rest of your delcarations for the required contract elements
// of the ITheyHaveInCommon interface...
}
public static class MyGlobalFunctions
{
public static string CommonFunction1( ITheyHaveInCommon incomingParm )
{
// now, you can act on ANY type of control that uses the
// ITheyHaveInCommon interface...
string Test = incomingParm.Name
+ incomingParm.GetOtherValue()
+ incomingParm.SomethingElse.ToString();
// blah blah with whatever else is in your "huge" function
return Test;
}
}
warning: lots of untested code here, wild guessing mostly since i disagree with the base assumption "no inheritance".
something like this should help you. create a new static class and paste your code in here.
public static class Display
{
public static void DisplayName<T>(T obj)
{
if ((T is Person) || (T is Country) || (T is whateveryouwant))
{
//do stuff
}
}
}
in your classes, refactor ShowDisplayName() to call that with "this" as parameter.
...
public void DisplayName()
{
DisplayName(this);
}
...
I wonder why your classes are not allowed to inherit it from a base class, since that's imho the right-est way to solve this.
A couple of options:
Make both classes implement an interface for the common members (Name) and add an extension method for the behaviour (or just a normal static method)
Create methods which take an instance and a lambda exppession to access the comment members, e.g.
public static void Display<T>(T item, Func<T, string> nameGetter)
You'd then call it with (say)
DisplayHelper.Display(person, p => p.Name);
The interface solution is the cleaner one, but using a delegate is more flexible - you don't need to be able to change the classes involved, and you can cope with small variations (e.g. PersonName vs FooName vs Name)
You can define that big method in a separate class and then call the method in both the above classes. For a static method, you can call the method using classname.methodname() syntax.
For a non static method, you will have to do this:
classname obj=new classname();
obj.methodname();

Why is it impossible to override a getter-only property and add a setter? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Why is the following C# code not allowed:
public abstract class BaseClass
{
public abstract int Bar { get;}
}
public class ConcreteClass : BaseClass
{
public override int Bar
{
get { return 0; }
set {}
}
}
CS0546 'ConcreteClass.Bar.set': cannot override because 'BaseClass.Bar' does not have an overridable set accessor
I think the main reason is simply that the syntax is too explicit for this to work any other way. This code:
public override int MyProperty { get { ... } set { ... } }
is quite explicit that both the get and the set are overrides. There is no set in the base class, so the compiler complains. Just like you can't override a method that's not defined in the base class, you can't override a setter either.
You might say that the compiler should guess your intention and only apply the override to the method that can be overridden (i.e. the getter in this case), but this goes against one of the C# design principles - that the compiler must not guess your intentions, because it may guess wrong without you knowing.
I think the following syntax might do nicely, but as Eric Lippert keeps saying, implementing even a minor feature like this is still a major amount of effort...
public int MyProperty
{
override get { ... } // not valid C#
set { ... }
}
or, for autoimplemented properties,
public int MyProperty { override get; set; } // not valid C#
It's possible.
tl;dr– You can override a get-only method with a setter if you want. It's basically just:
Create a new property that has both a get and a set using the same name.
override the prior get to alias the new get.
This enables us to override properties with get/set even if they lacked a setter in their base definition.
Situation: Pre-existing get-only property.
You have some class structure that you can't modify. Maybe it's just one class, or it's a pre-existing inheritance tree. Whatever the case, you want to add a set method to a property, but can't.
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
Problem: Can't override the get-only with get/set.
You want to override with a get/set property, but it won't compile.
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
Solution: Use an abstract intermediate layer.
While you can't directly override with a get/set property, you can:
Create a new get/set property with the same name.
override the old get method with an accessor to the new get method to ensure consistency.
So, first you write the abstract intermediate layer:
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
Then, you write the class that wouldn't compile earlier. It'll compile this time because you're not actually override'ing the get-only property; instead, you're replacing it using the new keyword.
public class D : C
{
private int _x;
public new virtual int X
{
get { return this._x; }
set { this._x = value; }
}
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
Result: Everything works!
var d = new D();
var a = d as A;
var b = d as B;
var c = d as C;
Print(a.X); // Prints "0", the default value of an int.
Print(b.X); // Prints "0", the default value of an int.
Print(c.X); // Prints "0", the default value of an int.
Print(d.X); // Prints "0", the default value of an int.
// a.X = 7; // Won't compile: A.X doesn't have a setter.
// b.X = 7; // Won't compile: B.X doesn't have a setter.
// c.X = 7; // Won't compile: C.X doesn't have a setter.
d.X = 7; // Compiles, because D.X does have a setter.
Print(a.X); // Prints "7", because 7 was set through D.X.
Print(b.X); // Prints "7", because 7 was set through D.X.
Print(c.X); // Prints "7", because 7 was set through D.X.
Print(d.X); // Prints "7", because 7 was set through D.X.
Discussion.
This method allows you to add set methods to get-only properties. You can also use it to do stuff like:
Change any property into a get-only, set-only, or get-and-set property, regardless of what it was in a base class.
Change the return type of a method in derived classes.
The main drawbacks are that there's more coding to do and an extra abstract class in the inheritance tree. This can be a bit annoying with constructors that take parameters because those have to be copy/pasted in the intermediate layer.
Bonus: You can change the property's return-type.
As a bonus, you can also change the return type if you want.
If the base definition was get-only, then you can use a more-derived return type.
If the base definition was set-only, then you can use a less-derived return type.
If the base definition was already get/set, then:
you can use a more-derived return type if you make it set-only;
you can use a less-derived return type if you make it get-only.
In all cases, you can keep the same return type if you want.
I stumbled across the very same problem today and I think I have a very valid reason for wanting this.
First I'd like to argue that having a get-only property doesn't necessarily translate into read-only. I interpret it as "From this interface/abstract class you can get this value", that doesn't mean that some implementation of that interface/abstract class won't need the user/program to set this value explicitly. Abstract classes serve the purpose of implementing part of the needed functionality. I see absolutely no reason why an inherited class couldn't add a setter without violating any contracts.
The following is a simplified example of what I needed today. I ended up having to add a setter in my interface just to get around this. The reason for adding the setter and not adding, say, a SetProp method is that one particular implementation of the interface used DataContract/DataMember for serialization of Prop, which would have been made needlessly complicated if I had to add another property just for the purpose of serialization.
interface ITest
{
// Other stuff
string Prop { get; }
}
// Implements other stuff
abstract class ATest : ITest
{
abstract public string Prop { get; }
}
// This implementation of ITest needs the user to set the value of Prop
class BTest : ATest
{
string foo = "BTest";
public override string Prop
{
get { return foo; }
set { foo = value; } // Not allowed. 'BTest.Prop.set': cannot override because 'ATest.Prop' does not have an overridable set accessor
}
}
// This implementation of ITest generates the value for Prop itself
class CTest : ATest
{
string foo = "CTest";
public override string Prop
{
get { return foo; }
// set; // Not needed
}
}
I know this is just a "my 2 cents" post, but I feel with the original poster and trying to rationalize that this is a good thing seems odd to me, especially considering that the same limitations doesn't apply when inheriting directly from an interface.
Also the mention about using new instead of override does not apply here, it simply doesn't work and even if it did it wouldn't give you the result wanted, namely a virtual getter as described by the interface.
I agree that not being able to override a getter in a derived type is an anti-pattern. Read-Only specifies lack of implementation, not a contract of a pure functional (implied by the top vote answer).
I suspect Microsoft had this limitation either because the same misconception was promoted, or perhaps because of simplifying grammar; though, now that scope can be applied to get or set individually, perhaps we can hope override can be too.
The misconception indicated by the top vote answer, that a read-only property should somehow be more "pure" than a read/write property is ridiculous. Simply look at many common read only properties in the framework; the value is not a constant / purely functional; for example, DateTime.Now is read-only, but anything but a pure functional value. An attempt to 'cache' a value of a read only property assuming it will return the same value next time is risky.
In any case, I've used one of the following strategies to overcome this limitation; both are less than perfect, but will allow you to limp beyond this language deficiency:
class BaseType
{
public virtual T LastRequest { get {...} }
}
class DerivedTypeStrategy1
{
/// get or set the value returned by the LastRequest property.
public bool T LastRequestValue { get; set; }
public override T LastRequest { get { return LastRequestValue; } }
}
class DerivedTypeStrategy2
{
/// set the value returned by the LastRequest property.
public bool SetLastRequest( T value ) { this._x = value; }
public override T LastRequest { get { return _x; } }
private bool _x;
}
You could perhaps go around the problem by creating a new property:
public new int Bar
{
get { return 0; }
set {}
}
int IBase.Bar {
get { return Bar; }
}
I can understand all your points, but effectively, C# 3.0's automatic properties get useless in that case.
You can't do anything like that:
public class ConcreteClass : BaseClass
{
public override int Bar
{
get;
private set;
}
}
IMO, C# should not restrict such scenarios. It's the responsibility of the developer to use it accordingly.
The problem is that for whatever reason Microsoft decided that there should be three distinct types of properties: read-only, write-only, and read-write, only one of which may exist with a given signature in a given context; properties may only be overridden by identically-declared properties. To do what you want it would be necessary to create two properties with the same name and signature--one of which was read-only, and one of which was read-write.
Personally, I wish that the whole concept of "properties" could be abolished, except that property-ish syntax could be used as syntactic sugar to call "get" and "set" methods. This would not only facilitate the 'add set' option, but would also allow for 'get' to return a different type from 'set'. While such an ability wouldn't be used terribly often, it could sometimes be useful to have a 'get' method return a wrapper object while the 'set' could accept either a wrapper or actual data.
Here is a work-around in order to achieve this using Reflection:
var UpdatedGiftItem = // object value to update;
foreach (var proInfo in UpdatedGiftItem.GetType().GetProperties())
{
var updatedValue = proInfo.GetValue(UpdatedGiftItem, null);
var targetpropInfo = this.GiftItem.GetType().GetProperty(proInfo.Name);
targetpropInfo.SetValue(this.GiftItem, updatedValue,null);
}
This way we can set object value on a property that is readonly. Might not work in all the scenarios though!
You should alter your question title to either detail that your question is solely in regards to overriding an abstract property, or that your question is in regards to generally overriding a class's get-only property.
If the former (overriding an abstract property)
That code is useless. A base class alone shouldn't tell you that you're forced to override a Get-Only property (Perhaps an Interface). A base class provides common functionality which may require specific input from an implementing class. Therefore, the common functionality may make calls to abstract properties or methods. In the given case, the common functionality methods should be asking for you to override an abstract method such as:
public int GetBar(){}
But if you have no control over that, and the functionality of the base class reads from its own public property (weird), then just do this:
public abstract class BaseClass
{
public abstract int Bar { get; }
}
public class ConcreteClass : BaseClass
{
private int _bar;
public override int Bar
{
get { return _bar; }
}
public void SetBar(int value)
{
_bar = value;
}
}
I want to point out the (weird) comment: I would say a best-practice is for a class to not use its own public properties, but to use its private/protected fields when they exist. So this is a better pattern:
public abstract class BaseClass {
protected int _bar;
public int Bar { get { return _bar; } }
protected void DoBaseStuff()
{
SetBar();
//Do something with _bar;
}
protected abstract void SetBar();
}
public class ConcreteClass : BaseClass {
protected override void SetBar() { _bar = 5; }
}
If the latter (overriding a class's get-only property)
Every non-abstract property has a setter. Otherwise it's useless and you shouldn't care to use it. Microsoft doesn't have to allow you to do what you want. Reason being: the setter exists in some form or another, and you can accomplish what you want Veerryy easily.
The base class, or any class where you can read a property with {get;}, has SOME sort of exposed setter for that property. The metadata will look like this:
public abstract class BaseClass
{
public int Bar { get; }
}
But the implementation will have two ends of the spectrum of complexity:
Least Complex:
public abstract class BaseClass
{
private int _bar;
public int Bar {
get{
return _bar;
}}
public void SetBar(int value) { _bar = value; }
}
Most Complex:
public abstract class BaseClass
{
private int _foo;
private int _baz;
private int _wtf;
private int _kthx;
private int _lawl;
public int Bar
{
get { return _foo * _baz + _kthx; }
}
public bool TryDoSomethingBaz(MyEnum whatever, int input)
{
switch (whatever)
{
case MyEnum.lol:
_baz = _lawl + input;
return true;
case MyEnum.wtf:
_baz = _wtf * input;
break;
}
return false;
}
public void TryBlowThingsUp(DateTime when)
{
//Some Crazy Madeup Code
_kthx = DaysSinceEaster(when);
}
public int DaysSinceEaster(DateTime when)
{
return 2; //<-- calculations
}
}
public enum MyEnum
{
lol,
wtf,
}
My point being, either way, you have the setter exposed. In your case, you may want to override int Bar because you don't want the base class to handle it, don't have access to review how it's handling it, or were tasked to hax some code real quick'n'dirty against your will.
In both Latter and Former (Conclusion)
Long-Story Short: It isn't necessary for Microsoft to change anything. You can choose how your implementing class is set up and, sans the constructor, use all or none of the base class.
Solution for only a small subset of use cases, but nevertheless: in C# 6.0 "readonly" setter is automatically added for overridden getter-only properties.
public abstract class BaseClass
{
public abstract int Bar { get; }
}
public class ConcreteClass : BaseClass
{
public override int Bar { get; }
public ConcreteClass(int bar)
{
Bar = bar;
}
}
This is not impossible. You simply have to use the "new" keyword in your property. For example,
namespace {
public class Base {
private int _baseProperty = 0;
public virtual int BaseProperty {
get {
return _baseProperty;
}
}
}
public class Test : Base {
private int _testBaseProperty = 5;
public new int BaseProperty {
get {
return _testBaseProperty;
}
set {
_testBaseProperty = value;
}
}
}
}
It appears as if this approach satisfies both sides of this discussion. Using "new" breaks the contract between the base class implementation and the subclass implementation. This is necessary when a Class can have multiple contracts (either via interface or base class).
Hope this helps
Because that would break the concept of encapsulation and implementation hiding. Consider the case when you create a class, ship it, and then the consumer of your class makes himself able to set a property for which you originally provide a getter only. It would effectively disrupt any invariants of your class which you can depend on in your implementation.
Because a class that has a read-only property (no setter) probably has a good reason for it. There might not be any underlying datastore, for example. Allowing you to create a setter breaks the contract set forth by the class. It's just bad OOP.
A read-only property in the base class indicates that this property represents a value that can always be determined from within the class (for example an enum value matching the (db-)context of an object). So the responsibillity of determining the value stays within the class.
Adding a setter would cause an awkward issue here:
A validation error should occur if you set the value to anything else than the single possible value it already has.
Rules often have exceptions, though. It is very well possible that for example in one derived class the context narrows the possible enum values down to 3 out of 10, yet the user of this object still needs to decide which one is correct. The derived class needs to delegate the responsibillity of determining the value to the user of this object.
Important to realize is that the user of this object should be well aware of this exception and assume the responsibillity to set the correct value.
My solution in these kind of situations would be to leave the property read-only and add a new read-write property to the derived class to support the exception.
The override of the original property will simply return the value of the new property.
The new property can have a proper name indicating the context of this exception properly.
This also supports the valid remark: "make it as hard as possible for misunderstandings to crop up" by Gishu.
Because at the IL level, a read/write property translates into two (getter and setter) methods.
When overriding, you have to keep supporting the underlying interface. If you could add a setter, you would effectively be adding a new method, which would remain invisible to the outside world, as far as your classes' interface was concerned.
True, adding a new method would not be breaking compatibility per se, but since it would remain hidden, decision to disallow this makes perfect sense.
Because the writer of Baseclass has explicitly declared that Bar has to be a read-only property. It doesn't make sense for derivations to break this contract and make it read-write.
I'm with Microsoft on this one.
Let's say I'm a new programmer who has been told to code against the Baseclass derivation. i write something that assumes that Bar cannot be written to (since the Baseclass explicitly states that it is a get only property).
Now with your derivation, my code may break. e.g.
public class BarProvider
{ BaseClass _source;
Bar _currentBar;
public void setSource(BaseClass b)
{
_source = b;
_currentBar = b.Bar;
}
public Bar getBar()
{ return _currentBar; }
}
Since Bar cannot be set as per the BaseClass interface, BarProvider assumes that caching is a safe thing to do - Since Bar cannot be modified. But if set was possible in a derivation, this class could be serving stale values if someone modified the _source object's Bar property externally. The point being 'Be Open, avoid doing sneaky things and surprising people'
Update: Ilya Ryzhenkov asks 'Why don't interfaces play by the same rules then?'
Hmm.. this gets muddier as I think about it.
An interface is a contract that says 'expect an implementation to have a read property named Bar.' Personally I'm much less likely to make that assumption of read-only if I saw an Interface. When i see a get-only property on an interface, I read it as 'Any implementation would expose this attribute Bar'... on a base-class it clicks as 'Bar is a read-only property'. Of course technically you're not breaking the contract.. you're doing more. So you're right in a sense.. I'd close by saying 'make it as hard as possible for misunderstandings to crop up'.

Categories