Delegating access to a class property instead of an object property - c#

I've been trying to figure out a way to deal with property mapping and naming programmatically. The thing is that I don't want to have to change multiple portions of code to be able to extend the map. The code I have right now is like this:
public static class Names
{
public const string Property = "propertyNameToBeUsedInJson";
}
...
switch(propertyName)
{
case Property:
user.propertyToBeMapped = json.propertyValue;
break;
}
What I really wanted was to be able to have some sort of dictionary where I could do something like:
Dictionary<string, Action>() { {"propertyNameToBeUsedInJson", <Class of User>.propertyToBeMapped} };
That means I would be delegating access to a property of a Class, not to a concrete object. This way I can iterate over this dictionary and if it contains the key I'm looking for, then I just go and change the property pointed by the value.
I think that a overhead during initialization is ok, but I don't want to use Reflection on a per call basis.
The questions is: Is it possible to use the second way having in mind the statement above? If so, how should I go for it?

Just to summarize the comments:
It is definitely possible to do it with a dictionary, but properties cannot be used quite this way. Remember that properties are just syntactic sugar so you don't have to write get/set methods yourself. The best way to get it into a dictionary is probably by wrapping it into a delegate:
new Dictionary<string, Func<YourClass, string>>()
{
{"propertyNameToBeUsedInJson",
instance => instance.YourProperty}
};
Then, you would use it very easily like this (error checking omitted):
user.propertyToBeMapped = dictionary[propertyName](yourClassInstance);
This will only work if the instance is always the same class. If not, the first parameter of the Func would have to be some base class (maybe even object) and then the delegate would have to do some type-checking and conversion.

Related

Properties and auto-implementations

I'm using .NET 4.5 in a VSTO addin for outlook 2013. I'm having some trouble fully grasping properties and accessors. Auto-implemented accessors which I assume are when you just write get; set; rather than get { //code }, etc. are also giving me trouble. I have a dictionary I use internally in my class. Here is my code:
private Dictionary<string, string> clientDict { get; set; }
private Dictionary<string, string> clientHistoryDict { get; set; }
then later on:
clientDict = new Dictionary<string, string>();
clientHistoryDict = new Dictionary<string, string>();
I am using the same names as the properties in the code later on, within the same class.
I never actually write:
private Dictionary<string, string> _clientDict; // etc.
to create the variables I just was using the property directly.
I tried changing my code to do this, and I had some issues and realized my understanding of properties is a bit mixed up.
Here are a few questions I need clarified that I can't seem to find the correct answer to.
First, is there any reason to use a private property? My dictionaries are never accessed outside of the class or in any derived classes so is there a reason to even use properties? I don't use any special validation or anything in the setter or anything like that.
Second, when I tried to change my code to use variables and then access them via the properties like your typical property example would, I ran into problems. I found an example where the getter was set to return _clientDict, but the setter was just set; It gave me the error: that I must give set a body because it's not abstract or partial. Why would it not auto-implement the setter for me in this instance?
Last, when I call new on the properties in the same class that it is declared in, what is the difference between doing that with a property and a normal variable of the same type? Do properties differ at all from variables in that case? Is it bad practice to use properties this way when it should be accomplished with private variables?
These may be some misguided questions but I can't find any other place that has the information to help me understand these distinctions. I've been playing around with properties to try and figure all of this out but I could use so me assistance.
First, is there any reason to use a private property?
Usually, no. Properties are great for encapsulation. One advantage (there are many more) of using a property is that it can do validations before assignment. When you have something private, you usually don't need to protect things from yourself. Also, properties have the advantage of setting different accessors (private, protected, etc), where fields do not.
Why would it not auto-implement the setter for me in this instance?
We have to understand that auto-implemented properties aren't black magic. The compiler will generate a private backing field for us, instead of providing one ourselfs. From his point of view, he sees that you have a getter that returns a private field, but the setter is automatic, thatusually would indicate some kind of logical error in your code. Why would you return one value but set a completely different one? When you create a property with a backing field, you have to provide both the getter and setters, those are the rules.
when I call new on the properties in the same class that it is
declared in, what is the difference between doing that with a property
and a normal variable of the same type?
Semantically, Nothing. new belongs to the type being constructed and will emit a constructor call. The difference is once the newly created object is assigned. A field will cause the compiler to emit a stfld opcode. For a property it'll emit a call to invoke the property setter. When you access a property, the compiler will end up calling get_YourPropertyName vs a ldfld on the field.
Is it bad practice to use properties this way when it should be
accomplished with private variables?
I wouldn't call it bad practice, but I would find it a bit weird to have a private property.
For more insights on fields and properties, see What is the difference between a Field and a Property in C#?
Is there any reason to use a private property?
No - that's the whole point of auto implementation. It saves you having to write all that extra code when all you want to do is get or set what's in the private member variable. .Net handles the creation of the shadowing private member variable behind the scenes.
When I tried to change my code to use variables and then access them via the properties like your typical property example would, I ran into problems. I found an example where the getter was set to return _clientDict, but the setter was just set; It gave me the error: that I must give set a body because it's not abstract or partial. Why would it not auto-implement the setter for me in this instance?
My understanding is that it's all or nothing with auto implementation. (Open to correction there though). That said I have seen code compile with the set block simply defined as set { }. Edit: Just to clarify the set { } block won't actually set the value, it essentially swallows the call and does nothing - it will compile though.
When I call new on the properties in the same class that it is declared in, what is the difference between doing that with a property and a normal variable of the same type? Do properties differ at all from variables in that case? Is it bad practice to use properties this way when it should be accomplished with private variables?
There is no real difference as far as I am aware. The exact same thing is happening, it's just that .Net is handling the plumbing for you.

Changing object properties from method (Best Practise)

I have a question for you. What is best practise to change object properties in method. Let's assume that I have a method like this:
public void ChangeThis(MyObj myobj)
{
myobj.Prop = 5;
}
Isn't better to return that object like we want to show that we change something?
public MyObj ChangeThis(MyObj myobj)
{
myobj.Prop = 5;
return myobj;
}
What is best practise to change object properties from methods?
The second method is bad as it is ambiguous as to whether a new instance of the object is created with the changed property or if the current instance is returned.
I would only use the second method if my objects were immutable.
The name of the method, ChangeThis, implies that the object is mutable, but by returning an object it suggests that they are not.
It depends.
While the first case appears more often, the second one is a useful, when you want to combine method calls in chain:
myObject
.ChangeThis()
.ChangeThat()
.ChangeSomethingElse();
I think, StringBuilder is a very good example:
sb
.AppendLine("1")
.AppendChar('2')
.AppendLine()
.ToSting();
The same API have model configuration classes from Entity Framework:
Property(_ => _.Name)
.HasColumnName("name")
.HasMaxLength(64)
.IsRequired();
Thus, sometimes this is very convenient way to call methods.
Imagine, how the code from above would look in 1st case:
sb.AppendLine("1");
sb.AppendChar('2');
sb.AppendLine();
sb.ToSting();
Sadly, isn't it?
If you want to make it obvious that the internal state of the object was changed, do it so by choosing a proper name for the method, and by adding proper XML documentation.
I don't think this is a good enough reason to return the object back to the client and, quite honestly, it's confusing. Are you returning a new object? Or is it the same object that was passed as a parameter? However, if the type is immutable, then you should return it.

Dynamically hooking up a class having different possible constructors

Let's say I have two classes that look like this:
public class ByteFilter
{
private Func <int, byte[]> readBytes;
private Action<byte[]> writeBytes;
public ByteFilter(Func <int, byte[]> readBytes, Action<byte[]> writeBytes)
{
this.readBytes = readBytes;
this.writeBytes = writeBytes;
}
}
public class PacketFilter
{
private Func<Packet> readPacket;
private Action<Packet> writePacket;
Public PacketFilter(Func<Packet> readPacket, Action<Packet> writePacket)
{
this.readBytes = readPacket;
this.writeBytes = writePacket;
}
}
Either class may be instantiated at runtime (via Activator.CreateInstance) to perform a filtering function. The read and write methods will be hooked up at runtime to methods from other classes that will provide and accept byte arrays or packets.
Within each filter is additional code that performs the filtering function:
public void Process()
{
while (!done)
{
byte[] data = ReadBytes(); // or ReadPacket()
// perform filtering on data
WriteBytes(data); // or WritePacket()
}
}
If only one of the above constructor signatures will be present in each filter, how do I determine (using Reflection) which constructor signature is present, so that I can hook up the appropriate methods at runtime?
Note: If I'm daffy and doing this the wrong way, I'd like to know that too.
Can't you do something like?
bool packetConstructor =
typeof(PacketFilter).GetConstructors()
.Any(c => c.GetParameters()
.Any(p => p.ParameterType
== typeof(Func<Packet>)));
replacing typeof(PacketFilter) with appropriate instance.
An option that has not been mentioned is to use Fasterflect, a library created to make reflection easier and faster where possible.
It also has a couple of features built on top of the core reflection capabilities, one of which is the ability to construct objects when you don't know what constructors are available.
var instance = typeof(PacketFilter).TryCreateInstance( new { Foo = "Bar" } );
There are also overloads for passing in a dictionary of named values or discrete name and value arrays. The latest code also provides extensions for constructing objects just from an ordered list of values, matching them in order to parameters by their type.
Fasterflect will automatically pick the constructor with the most matching arguments. If it's unable to use a value it'll try to set a matching property after construction. And you have the option of requiring all values to be used.
Disclaimer: I'm a contributor to the project.
You can enumerate the constructors (to get the one constructor) and then enumerate the parameters of the constructor. Since the parameters are expected to be generic types, you then need to enumerate the generic type parameters for each generic constructor parameter. Note that all of this is very hacky and I would recommend finding a better solution. Reflection is a powerful tool and using it introduces complexity; if there is a less complex solution (such as a factory pattern, perhaps), that would be preferable. It's also possible that your need to solve this particular problem reflects excessive complication in your existing design. If you simplify the original design, you may find that the technical problem goes away.

What is the best way to support new property in legacy code

I have a architecture question about legacy.
For example I have a class that using everywhere in project. Projects don't have any Unit Tests
public class LegacyObject
{
public Dictionary<string, string[]> MyLegacyProperty { get;set;}
}
I need to change dictionary type to other type for example IEnumerable<KeyValuePair<TKey, TValue>>.
What is the best way to change it and don't change the part of code where dictionary MyLegacyProperty using.
Well, Dictionary<T,U> does implement IEnumerable<KeyValuePair<T,U>>, so anything that wants to use the IEnumerable could reference the Dictionary property and it would work. Since you want to make that change, I'm assuming you want to do something that a Dictionary doesn't allow, duplicate keys, perhaps.
If the replacement property can be converted to a Dictionary, I'd do something like this. Have you old property sitting next to your new property, and deal with conversions in the old property's getter and setter. Note that this pattern will fail if the use case for MyLegacyProperty is to retrieve it, modify it, and not set it back; you'll need to do something akin to ObservableCollection in that case. (Is there an ObservableDictionary?)
public class LegacyObject
{
public Dictionary<string, string[]> MyLegacyProperty
{
get { return ConvertMyNewProperty(); }
set { this.MyNewProperty = ConvertMyLegacyProperty(value); }
}
IEnumerable<KeyValuePair<string, string[]>> MyNewProperty { get; set; }
}
If the replacement property can't be converted to a Dictionary, then you're talking about making a real change to the external interface of your class. I don't believe there's any substitute for biting the bullet, and making the change with no backward compatibility. The only tip I can give you is to make the new property have a different name from the old one: You'll be able to use Find In Files to find the code you need to change, and it will make it so the compiler errors you get are clear and unambiguous.
If you can create a new property with a new name, you could mark the old one as [Obsolete] and slowly migrate your code base to use the new property, until there're no references to the old one and you can delete it.
If you must use the old property name, and if the property is only used within one solution in Visual Studio, you can use the renaming refactoring and change the name to something like MyLegacyProperty_Old and then create the new property with the old name.
In either case, it's a good idea to write some unit tests for your class.

Possible to create a new instance of a type without reflection?

I have a function that at the moment takes a Type variable. This function sticks it in a list and such and eventually needs will create a class of that type.
Right now I do that with
object o=MyType.GetConstructors()[0].Invoke(new object[0]);
which is pretty hacky and also will not work in medium trust due to reflection(I think). Is there a better way of doing this without reflection?
The Type is defined this way as part of a function. I need the class to be created "lazily" because it may not be created in the application if it's not needed. I use it for example like
AddToList(typeof(Whatever));
Note, I'm open to suggestions on changing the function calling. I just need the object to be created lazily and for to store the type(or however to create an object of the type) in a list.
I've considered lambdas but I'm not sure they'd work here.
Using Generics:
public void Method<T>() where T : class, new()
{
//code
T t = new T();
}
Using Activator (still reflection, meh):
object t = Activator.CreateInstance(yourTypeVariable);
Personally, I would prefer the first solution due to being strongly typed. However, you should be aware that both methods only allow for parameterless constructors. If you need to pass parameters, you will need reflection or expression trees.
Another alternative solution is FormatterServices.
object instance = FormatterServices.GetUninitializedObject(typeof(MyClass));
Note that the instance is created without any fields/properties initialized, even you have
class MyClass
{
public int i = 99;
public Object o = new object();
}
instance.i will be 0 and instance.o will be null. It's quite hard to provide a pure non-reflection solution(because always you need to call o.GetType()). This solution essentially serialize the object and then deserialize it to an object, so you don't need to use reflection to call its constructor. But there is still reflection when serialization/deserialization.
After further research on lambdas, I've discovered they will give me a much more elegant solution and it does not use reflection
So I used in my list definition
public delegate MyBaseType TypeCreator();
...
public TypeCreator Creator;
and in my function call, a simple and elegant lambda:
AddToList(()=>{return new MyType();});
I think this is quite a bit cleaner than my reflection method because it allows putting parameters into the constructor, and a few other reasons outside of the scope of this question. (It just goes with my project well)

Categories