I mistakenly posted this question already at the SharePoint part.
I need to map one model onto an other. Everything works well but the last property throws a TargetParameterCountException. The property which throws the exception is called "Item" this property is not defined by me, I assume that this is a property from the dictionary.
I already tried to use all five parameters instead of only one (as described here Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch) but unfortunately i will get the same exception. I would really appreciate it if someone could help me.
Kinde Regards and Thanks
Sandro
That is a excerpt of the Source Model, all other properties are implemented in exactly the same way:
public class DataModel : Dictionary<string, object> {}
public class DiscussionDataModel : DataModel
{
public DiscussionDataModel(Dictionary dictionary) : base(dictionary){}
public FieldUserValue Author
{
get { return (FieldUserValue) this["Author"]; }
set { this["Author"] = value; }
}
public double AverageRating
{
get { return (double) this["AverageRating"]; }
set { this["AverageRating"] = value; }
}
}
And that is a excerpt the target Model, all other properties are implemented in exactly the same way:
public class DiscussionModel : BaseModel
{
public FieldUserValue Author { get; set; }
public double AverageRating { get; set; }
}
And this is the generic extension method to map the DataModel onto the BaseModel:
public static T ToModel(this DataModel dataModel) where T : BaseModel
{
try
{
T model = Activator.CreateInstance();
if (dataModel != null)
{
PropertyInfo[] propertyInfos = dataModel.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo propertyInfo in propertyInfos)
{
object value = propertyInfo.GetValue(dataModel);
if (value == null) { break; }
PropertyInfo modelPropertyInfo = model.GetType().GetProperty(propertyInfo.Name);
modelPropertyInfo?.SetValue(model, value);
}
return model;
}
}
catch (Exception ex)
{
throw;
}
return null;
}
The problem is that the Item property is indexed, i.e. it has a parameter. C# normally does not allow this, but other .NET languages such as VB.NET do. Thus, this concept is known to the CLR and thus also to Reflection. In C#, there is only one way to create an indexed property, namely through an indexer. What this does at a CLR-level is to create an indexed propery called Item, so you might have just stumbled across an indexer.
So the solution is to check the property info whether it has parameters and continue the for loop if this is the case. There is no chance for you to know generically what objects to pass into an indexed property.
Related
I've created a data class that I plan to use to send data to be persisted in the database and to return data from the database in a strongly typed way. In addition to its properties, the class contains a Dictionary that I populate in the constructor with the name of and reference to each property. This makes the properties enumerable and enables me to iterate through them using 'foreach'.
This works great when setting property values and sending the object to be persisted in the database. I can iterate through the Dictionary keys, get the value of each property, and add a SqlParameter for each property using the key as the parameter name and the property value as the parameter value.
However, going the other way doesn't work. I can iterate through the Dictionary keys and get the value of each column in each row of the SqlDataReader, but when I try to assign these values to my data object using the Dictionary's reference to the corresponding object property, a curious thing occurs. The assignments succeed, BUT the data object properties all retain their initial, default values. I can view the data object properties and see these initial, default values. I can also view the Dictionary entry values and see the updated values that were read and assigned from the SqlDataReader.
This makes no sense. The Dictionary is supposed to provide access to each property (the 'object' generic type) via its key (the 'string' generic type), but its acting like its maintaining a separate copy of each Dictionary 'KeyValuePair'.
What gives?
I'm doing all this in C# in the context of an ASP.NET Core 2.1.1 project running on macOS 10.13.6 High Sierra.
I've searched StackOverflow extensively, and I see lots of recommendations for using reflection to do this type of thing. I'll refactor my code to use reflection if necessary, but I'd really like to understand where and how my mental model for what's happening is off.
An explanation of what's happening and why would be MOST appreciated.
Example Data Class with Property Dictionary
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
namespace MyOrg.MyProj.Data
{
[DataContract]
public class DataObj
{
#region Attributes
[Required]
[DataMember(Name = "dataObjectId")]
public Int64 DataObjectId { get; set; }
[Required]
[DataMember(Name = "guid")]
public Guid Guid { get; set; }
public virtual Dictionary<string, object> DataMembers { get; set; } //NOTE: Implements the IEnumerable interface in order to support 'foreach' operations, etc on 'DataObj' class attributes
#endregion Attributes
#region Constructors
public DataObj(Int64 dataObjectId, Guid guid)
{
try
{
DataObjectId = dataObjectId;
Guid = guid;
DataMembers = new Dictionary<string, object>
{
{ "DataObjectId", DataObjectId },
{ "Guid", Guid }
};
}
catch (Exception e)
{
Console.WriteLine($"RUNTIME EXCEPTION while INSTANTIATEing DataObj, " + e.Message + ", " + e.StackTrace);
}
}
#endregion Constructors
#region Methods
/// <summary>
/// Implements the IEnumerable interface in order to support 'foreach' operations, etc on 'DataObj' class attributes
/// </summary>
/// <returns>Enumerator</returns>
public Dictionary<string, object>.Enumerator Enumerator()
{
return DataMembers.GetEnumerator(); //NOTE: Return the Dictionary object's IEnumerator rather than implementing IEnumerable for the 'DataObj' class itself
}
#endregion Methods
Example Data Access Class (excerpt)
reader = command.ExecuteReader();
dataObjList = new List<DataObj>();
if (reader.HasRows)
{
while (reader.Read())
{
tempDataObj = new DataObj(-1, new Guid("00000000-0000-0000-0000-000000000000"));
keys = new List<String>(tempDataObj.DataMembers.Keys); //NOTE: Can't modify a Dictionary while iterating through it. See the 'Why This Error?' section of https://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute
foreach (String key in keys)
{
tempDataObj.DataMembers[key] = reader[key];
}
dataObjList.Add(tempDataObj);
For 'key' = 'DataObjectId', 'Guid', etc, I expect the value of tempDataObj.DataObjectId, tempDataObj.Guid, etc to be set to the value returned from the database in 'reader[key]'.
Instead, it retains its initial, default value as set in the constructor, i.e. '-1'. This is true for both value and reference data types.
However, when I inspect tempDataObj.DataMembers["DataObjectId"], it has been set to the value returned from the database in 'reader[key]'.
Inspecting the Object Property and Dictionary Values
tempDataObj.DataMembers["DataObjectId"] should be referencing the tempDataObj.DataObjectId property, etc, but the Dictionary appears to be maintaining its own value rather than providing an object reference to the 'DataObjectId' property.
What's going on here? Thank you!
You're storing the data twice - once in a Dictionary, and a second time in a field. There's no need to store it twice. Just do this:
[DataContract]
public class DataObj
{
[Required]
[DataMember(Name = "dataObjectId")]
public Int64 DataObjectId
{
get => (long)DataMembers[nameof(DataObjectId)];
set => DataMembers[nameof(DataObjectId)] = value;
}
[Required]
[DataMember(Name = "guid")]
public Guid Guid
{
get => (Guid)DataMembers[nameof(Guid)];
set => DataMembers[nameof(Guid)] = value;
}
public Dictionary<string, object> DataMembers { get; } = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public DataObj(Int64 dataObjectId, Guid guid)
{
DataObjectId = dataObjectId;
Guid = guid;
}
public Dictionary<string, object>.Enumerator Enumerator()
{
return DataMembers.GetEnumerator();
}
}
FYI, you can also look at using an ExpandoObject, which lets you access something in a way that looks like a class, but is really just a Dictionary. https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=netframework-4.7.2
I have never used an ExpandoObject and I think the whole idea is as perverse as VBA's default of option explicit being off and On Error Resume Next. On the other hand, I don't deal with databases much.
I see two (main) routes to do what you want. In both cases you should implement a custom indexer.
In the indexer explicitly check the name given to it and get or set the field or property accordingly.
Use reflection, i.e. GetField() or GetProperty(), to get the field or property and GetValue() or SetValue() to get or set the values.
Below is a demonstration where ExposeByExplicitIndexer0 and its descendants use way 1 and ExposeByIndexerUsingReflection0 and its descendants use way 2.
public class ExposeByExplicitIndexer0
{
public int Int0 = 1;
public string String0 = "A";
public virtual object this[string name]
{
get
{
switch (name)
{
case "Int0":
return this.Int0;
case "String0":
return this.String0;
default:
throw new IndexOutOfRangeException();
}
}
set
{
switch (name)
{
case "Int0":
this.Int0 = (int)value;
break;
case "String0":
this.String0 = (string)value;
break;
default:
throw new IndexOutOfRangeException();
}
}
}
}
public class ExposeByExplicitIndexer1 : ExposeByExplicitIndexer0
{
protected Guid _Guid1 = Guid.Empty;
public Guid Guid1
{
get
{
return this._Guid1;
}
set
{
this._Guid1 = value;
}
}
public override object this[string name]
{
get
{
switch (name)
{
case "Guid1":
return this.Guid1;
default:
return base[name];
}
}
set
{
switch (name)
{
case "Guid1":
this.Guid1 = (Guid)value;
break;
default:
base[name] = value;
break;
}
}
}
}
public class ExposeByIndexerUsingReflection0
{
public object this[string name]
{
get
{
FieldInfo fieldInfo;
if ((fieldInfo = this.GetType().GetField(name)) != null)
{
return fieldInfo.GetValue(this);
}
PropertyInfo propertyInfo;
if ((propertyInfo = this.GetType().GetProperty(name)) != null)
{
return propertyInfo.GetValue(this);
}
throw new IndexOutOfRangeException();
}
set
{
FieldInfo fieldInfo;
if ((fieldInfo = this.GetType().GetField(name)) != null)
{
fieldInfo.SetValue(this, value);
return;
}
PropertyInfo propertyInfo;
if ((propertyInfo = this.GetType().GetProperty(name)) != null)
{
propertyInfo.SetValue(this, value);
return;
}
throw new IndexOutOfRangeException();
}
}
}
public class ExposeByIndexerUsingReflection1 : ExposeByIndexerUsingReflection0
{
public int Int1 = 1;
public string String1 = "A";
}
public class ExposeByIndexerUsingReflection2 : ExposeByIndexerUsingReflection1
{
protected Guid _Guid2 = Guid.Empty;
public Guid Guid2
{
get
{
return this._Guid2;
}
set
{
this._Guid2 = value;
}
}
}
public class Program
{
static void Main(string[] args)
{
Guid newGuid = Guid.NewGuid();
Console.WriteLine("Expose by explicit indexer:");
ExposeByExplicitIndexer1 exposeByExplicitIndexer1 = new ExposeByExplicitIndexer1();
exposeByExplicitIndexer1["Int0"] = 10;
exposeByExplicitIndexer1["String0"] = "AAA";
exposeByExplicitIndexer1["Guid1"] = newGuid;
Console.WriteLine("output via indexer:");
Console.WriteLine(exposeByExplicitIndexer1["Int0"]);
Console.WriteLine(exposeByExplicitIndexer1["String0"]);
Console.WriteLine(exposeByExplicitIndexer1["Guid1"]);
Console.WriteLine("output via fields or properties:");
Console.WriteLine(exposeByExplicitIndexer1.Int0);
Console.WriteLine(exposeByExplicitIndexer1.String0);
Console.WriteLine(exposeByExplicitIndexer1.Guid1);
Console.WriteLine("Expose by indexer using reflection:");
ExposeByIndexerUsingReflection2 exposeByIndexerUsingReflection2 = new ExposeByIndexerUsingReflection2();
exposeByIndexerUsingReflection2["Int1"] = 10;
exposeByIndexerUsingReflection2["String1"] = "AAA";
exposeByIndexerUsingReflection2["Guid2"] = newGuid;
Console.WriteLine("output via indexer:");
Console.WriteLine(exposeByIndexerUsingReflection2["Int1"]);
Console.WriteLine(exposeByIndexerUsingReflection2["String1"]);
Console.WriteLine(exposeByIndexerUsingReflection2["Guid2"]);
Console.WriteLine("output via fields or properties:");
Console.WriteLine(exposeByIndexerUsingReflection2.Int1);
Console.WriteLine(exposeByIndexerUsingReflection2.String1);
Console.WriteLine(exposeByIndexerUsingReflection2.Guid2);
Console.Read();
}
}
In way 1 every descendant that adds new fields or properties has to extend the indexer. That's more work in general but also offers an easy way of flexibility i.e. for adding some casts or expose some field or property via an alias, etc.
Way 2 needs less effort in the descendants. But being as flexible as in way 1 may become more difficult in turn. Maybe some mixed solution is also possible overriding the indexer in some descendant to inject special logic.
I want to receive ObservableCollection<T> where T is unknow. (I'm making like a library, so I don't know what class is assigned)
The hole story like this.
1) I offer a property named Prop and coder assign ObservableCollection<T> to Prop like following
Prop = ObservableCollection<T>; // where T is class which coder defined
2) Then I receive Prop and get information use reflection's methods (eg. GetProperties, GetType, FullName so on..)
Here, I don't know how to design the property Prop
I've designed it as
ObservableCollection<object> prop;
public ObservableCollection<object> Prop
{
set
{
prop = value;
// here, I'll make process like
// value.GetType().GetProperties() etc.
}
get
{
return prop;
}
}
But as you know if I assign ObservableCollection<TestClass> test = new ObservableCollection<TestClass>(); to Prop, a error occurred that
Cannot implicitly convert type 'System.Colletions.ObjectModel.ObservableCollection<TestClass>' to 'System.Collections.ObjectModel.ObservableCollection<object>'
If you let me know how, it will be pleasure
It seems like you need a class with generic definition:
class TestGeneric<T>
{
private ObservableCollection<T> _prop;
public ObservableCollection<T> Prop
{
get
{
return _prop;
}
set
{
_prop = value;
// here, I'll make process like
// value.GetType().GetProperties() etc.
}
}
}
class TestClass
{ }
so that you can use generic property:
var generic = new TestGeneric<TestClass>();
generic.Prop = new ObservableCollection<TestClass>();
This seems like the most basic thing ever but somehow I couldnt find the answer and couldnt figure it out.
Lets say I have a custom class:
public class WineCellar
{
public string year;
public string wine;
public double nrbottles;
}
Now I would like a function:
WineCellar ex = new WineCellar();
ex.members();
This should return: year, wine, nrbootles.
And:
ex.members().types();
Should return: string, string, double
I guess on the same note, lets say you have one instance {2010, Rioja, 6}. Is there syntax that returns these by indexing? i.e.
ex[1]
or
ex.{1}
that returns 2010?
Sorry for the basic question.
As Michelle said in the comments, this sounds like a wrong approach to a bigger problem.
However, if you do need this kind of things, you can get the using reflection:
//returns a list of propertyInfo objects for the class
// with all kinds of usefull information
public List<PropertyInfo> GetMemberInfos()
{
return this.GetType().GetProperties().ToList();
}
//returns a list of property names
public List<string> GetMemberNames
{
return this.GetType().GetProperties().Select(pi => pi.Name).ToList();
}
//returns a list of names of the property types
public List<string> GetMemberTypeNames
{
return this.GetType().GetProperties().Select(pi => pi.PropertyType.Name).ToList();
}
//indexer that uses the property name to get the value
//since you are mixing types, you can't get more specific than object
public object this[string property]
{
get { return this.GetType().GetProperty(property).GetValue(this); }
set { this.GetType().GetProperty(property).SetValue(this, value); }
}
//indexer that uses the property index in the properties array to get the value
public object this[int index]
{
get { return this.GetType().GetProperties()[index].GetValue(this); }
set { this.GetType().GetProperties()[index].SetValue(this, value); }
}
Note that all of these methods are very slow, because in general, reflection is slow. You can try to cache some thing to speed it up.
Also, the last method is downright dangerous. It will (try to) read and write to an array that does not have a guaranteed order. In fact, the documentation specifies:
The GetProperties method does not return properties in a particular
order, such as alphabetical or declaration order. Your code must not
depend on the order in which properties are returned, because that
order varies.
For example, if you change your class to:
public class WineCellar
{
public string year;
public string region;
public string wine;
public double nrbottles;
}
and you were used to using winecellar[1] = "Pinot Noir" that will most likely now update the region property, instead of the wine property.
This is how you would implement Members method (In case if you wanted property names as strings)
public List<string> Members()
{
List<string> propNames = new List<string>();
foreach (var prop in typeof(WineCellar).GetProperties())
{
propNames.Add(prop.Name);
}
return propNames;
}
And this is how you would implement Types (In same case)
public List<string> Types()
{
List<string> propTypes = new List<string>();
foreach (var prop in typeof(WineCellar).GetProperties())
{
propTypes.Add(prop.PropertyType.ToString());
}
return propTypes ;
}
And the last thing if you want to get values of the parameters like this ex[n] you can just make a simple indexer in you class like this
public string this[int n]
{
get
{
int current = 0;
foreach (var prop in typeof(WineCellar).GetProperties())
{
if (current == n)
return prop.GetValue(this, null).ToString();
current++;
}
return null;
}
}
but for these methods to work you should change your variables into properties like this
public class WineCellar
{
public string Year { get; set; }
public string Wine { get; set; }
public double Nrbottles { get; set; }
}
You can use reflection
foreach (var prop in typeof(WineCellar).GetProperties())
{
if (prop.PropertyType == typeof(double) || prop.PropertyType == typeof(double?))
{
}
}
to get the value, you can do:
prop.GetValue(obj);
I'm using EF4.3 so I'm referring to entities, however it could apply to any class containing properties.
I'm trying to figure out if its possible to compare 2 entities. Each entity has properties that are assigned values for clarity let say the entity is 'Customer'.
public partial class Customer
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
...
...
}
The customer visits my website and types in some details 'TypedCustomer'. I check this against the database and if some of the data matches, I return a record from the database 'StoredCustomer'.
So at this point I've identified that its the same customer returning but I wan't to valid the rest of the data. I could check each property one by one, but there are a fair few to check. Is it possible to make this comparison at a higher level which takes into account the current values of each?
if(TypedCustomer == StoredCustomer)
{
.... do something
}
If you're storing these things in the database, it is logical to assume you'd also have a primary key called something like Id.
public partial class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
...
...
}
Then all you do is:
if(TypedCustomer.Id == StoredCustomer.Id)
{
}
UPDATE:
In my project, I have a comparer for these circumstances:
public sealed class POCOComparer<TPOCO> : IEqualityComparer<TPOCO> where TPOCO : class
{
public bool Equals(TPOCO poco1, TPOCO poco2)
{
if (poco1 != null && poco2 != null)
{
bool areSame = true;
foreach(var property in typeof(TPOCO).GetPublicProperties())
{
object v1 = property.GetValue(poco1, null);
object v2 = property.GetValue(poco2, null);
if (!object.Equals(v1, v2))
{
areSame = false;
break;
}
});
return areSame;
}
return poco1 == poco2;
} // eo Equals
public int GetHashCode(TPOCO poco)
{
int hash = 0;
foreach(var property in typeof(TPOCO).GetPublicProperties())
{
object val = property.GetValue(poco, null);
hash += (val == null ? 0 : val.GetHashCode());
});
return hash;
} // eo GetHashCode
} // eo class POCOComparer
Uses an extension method:
public static partial class TypeExtensionMethods
{
public static PropertyInfo[] GetPublicProperties(this Type self)
{
self.ThrowIfDefault("self");
return self.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where((property) => property.GetIndexParameters().Length == 0 && property.CanRead && property.CanWrite).ToArray();
} // eo GetPublicProperties
} // eo class TypeExtensionMethods
Most simple seems to use reflexion : get the properties and/or fields you want to compare, and loop through them to compare your two objects.
This will be done with getType(Customer).getProperties and getType(Customer).getFields, then using getValue on each field/property and comparing.
You might want to add custom informations to your fields/properties to define the ones that needs
comparing. This could be done by defining a AttributeUsageAttribute, that would inherit from FlagsAttribute for instance. You'll then have to retrieve and handle those attributes in your isEqualTo method.
I don't think there's much of a purpose to checking the entire object in this scenario - they'd have to type every property in perfectly exactly as they did before, and a simple "do they match" doesn't really tell you a lot. But assuming that's what you want, I can see a few ways of doing this:
1) Just bite the bullet and compare each field. You can do this by overriding the bool Equals method, or IEquatable<T>.Equals, or just with a custom method.
2) Reflection, looping through the properties - simple if your properties are simple data fields, but more complex if you've got complex types to worry about.
foreach (var prop in typeof(Customer).GetProperties()) {
// needs better property and value validation
bool propertyMatches = prop.GetValue(cust1, null)
.Equals(prop.GetValue(cust2, null));
}
3) Serialization - serialize both objects to XML or JSON, and compare the strings.
// JSON.NET
string s1 = JsonConvert.SerializeObject(cust1);
string s2 = JsonConvert.SerializeObject(cust2);
bool match = s1 == s2;
I would like to automatically generate SQL statements from a class instance. The method should look like Update(object[] Properties, object PrimaryKeyProperty). The method is part of an instance (class, base method - generic for any child). Array of properties is an array of class properties, that will be used in update statement. Property names are equal to table field names.
The problem is that I can't get property names.
Is there any option to get a property name inside class instance?
sample:
public class MyClass {
public int iMyProperty { get; set; }
public string cMyProperty2 { get; set; }
{
main() {
MyClass _main = new MyClass();
_main.iMyProperty.*PropertyName* // should return string "iMyProperty"
{
I am aware of PropertyInfo, but I don't know hot to get the ID of a property from GetProperties() array.
Any suggestion?
Just wrote an implementation of this for a presentation on lambdas for our usergroup last Tuesday.
You can do
MembersOf<Animal>.GetName(x => x.Status)
Or
var a = new Animal()
a.MemberName(x => x.Status)
the code:
public static class MembersOf<T> {
public static string GetName<R>(Expression<Func<T,R>> expr) {
var node = expr.Body as MemberExpression;
if (object.ReferenceEquals(null, node))
throw new InvalidOperationException("Expression must be of member access");
return node.Member.Name;
}
}
Link to the presentation and code samples.
Also in SVN (more likely to be updated): http://gim-projects.googlecode.com/svn/presentations/CantDanceTheLambda
I found a perfect solution in This Post
public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
return (propertyExpression.Body as MemberExpression).Member.Name;
}
And then for the usage :
var propertyName = GetPropertyName(
() => myObject.AProperty); // returns "AProperty"
Works like a charm
You can do something like this:
Type t = someInstance.getType();
foreach (MemberInfo mi in t.GetMembers())
{
if (mi.MemberType == MemberTypes.Property)
{
Console.WriteLine(mi.Name);
}
}
to get all the property names for instance's type.
You can get the name (I assume that's what you meant by ID) of a property using PropertyInfo.Name. Just loop through the PropertyInfo[] returned from typeof(className).GetProperties()
foreach (PropertyInfo info in typeof(MyClass).GetProperties())
{
string name = info.Name;
// use name here
}
Since you already have an explicit handle to the specific property you want, you know the name - can you just type it?
Not 100% sure if this will get you what you're looking for, this will fetch all properties with [Column] attribute inside your class:
In the datacontext I have:
public ReadOnlyCollection<MetaDataMember> ColumnNames<TEntity>( )
{
return this.Mapping.MappingSource.GetModel(typeof(DataContext)).GetMetaType(typeof(TEntity)).DataMembers;
}
Fetching the table column-names that are properties inside the class:
MyDataContext db = GetDataContext();
var allColumnPropertyNames = db.ColumnNames<Animal>().Where(n => n.Member.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false).FirstOrDefault() != null).Select(n => n.Name);
Let's say (from the first sample, method update of a class MyClass):
public class MyClass {
public int iMyStatusProperty { get; set; }
public int iMyKey { get; set; }
public int UpdateStatusProperty(int iValue){
this.iMyStatusProperty = iValue;
return _Update( new[iMyStatusProperty ], iMyKey); // this should generate SQL: "UPDATE MyClass set iMyStatusProperty = {iMyStatusProperty} where iMyKey = {iMyKey}"
}
{iMyStatusProperty} and {iMyKey} are property values of a class instance.
So, the problem is how to get property name (reflection) from a property without using names of properties as strings (to avoid field name typos).