filling object property with string directly - c#

I know how to cast implicity object to string but is it possible to cast string to object property?
I would like to fill object property directly, without using code: ob.property="text".
Instead I would like to use: ob="text"
Example:
class Person
{
public string Name { get; set; }
public string Name2 { get; set; }
public string Name { get; set; }
.
.
.
}
var a=new Person();
I would like to fill property Name with string "text1"
Is there any way to do this : a="text1" instead of a.Name="text1" ?
I know how to cast implicity object to string but is it possible to cast string to object property?

The closest you can achieve this is using implicit operators overload.
For example,
class Person
{
public string Name { get; set; }
public static implicit operator string(Person person)
{
return person.Name;
}
public static implicit operator Person(string name)
{
return new Person(){Name=name};
}
}
Now you can assign as
var person = new Person();
person = "Test Name";
But you would need to evaluate whether this effort is worth it.

While it is a stupid idea, you could use a bit of reflection and as #Bizhan said an indexer to achieve something similar.
static void Main(string[] args)
{
MyClass mc = new MyClass();
mc[0] = "Test Name";
mc[1] = "Test Surname";
}
class MyClass
{
public string this[int i]
{
set
{
var props = this.GetType().GetProperties();
props[i + 1].SetValue(this, value);
}
}
public string Name { get; private set; }
public string Surname { get; private set; }
}
The only problem with this is that it'll only work on String types, the indexer must be first in the class, exception will be thrown when property index will be outside available number of properties, it uses index based property access but that could be automated using a for loop. Then again you could modify this code to do various checks.
It still makes no reason why one would need this - if you explain your use case better there might be better ways to go on about your problem.

Related

Initializing property value in one class using the return value of a method in a different class

I have the following structure:
public class LogicStatement : ILogicStatement
{
public string TestLogic { get; set; }
public string CompareLogic { get; set; }
public string Operator { get; set; }
public string Expression();
public bool Value();
}
public class Test : ITest
{
public int TestId { get; set; }
public int LiteralId { get; set; }
public string TestName { get; set; }
public string TestText { get; set; }
public string TestDisplayName { get; }
**public ILogicStatement LogicStatement { get; set; }**
public string Expression { get; set; }
public bool Value { get; set; }
}
public class Literal : ILiteral
{
some property members...
**public List<ITest> Tests {get; set;}**
some method members...
}
Note that the class Test has a member of type LogicStatement, and the class Literal has a member of type List.
Note also that all classes have properties and methods that share the same name: Expression, Value, Expression(), Value().
The value of Expression and Value (properties and methods) depend on values in the LogicStatement class.
Throughout the whole project, I use the Interface Type for to instantiate each object to adhere with Dependency Inversion. To support this, I use a factory-like design to create new instances of Test and LogicStatement.
Example:
public static class Factory
{
public static ILogicStatement CreateLogicStatement()
{
return new LogicStatement();
}
public static ITest CreateTest()
{
return new Test(CreateLogicStatement());
}
public static List<ITest> CreateTests()
{
return new List<ITest>();
}
//repeat the same for evey other class.
}
My goal is to have Expression() and Value() be calculated only once in the bottom level class (LogicStatement), and somehow get transfered to their counterpart properties in the higher level classes.
I'm getting the data from Dapper and it looks like all the nested objects are returned from the Dapper module correctly with the same nested structure I intended, and with the right values for all of their members. All of them but Expression, Expression(), Value, Value() are null.
my constructors look like this:
public LogicStatement()
{
Expression();
Value();
}
public Test(ILogicStatement logicStatement)
{
_logicStatement = logicStatement;
Expression = _logicStatement.Expression();
Value = _logicStatement.Value();
}
public Literal(ITest test)
{
_test = test;
Expression = _test.Expression;
Value = _test.Value;
}
and my main:
List<ILiteral> literals = Factory.CreateLiterals();
List<ITest> tests = Facotry.CreateTests();
List<ILogicStatement> logicStatements = Factory.CreateLogicStatements();
literals = GetDataFromDapper();
This last line seems to assign correct values to all other members on all hierarchies. But I cannot get Expression and Value to be anything other than null.
If I test LogicStatement.Expression() and LogicStatement.Value() standalone, they do return the expexted values. but starting at the first parent class Test, these properties are all null.
I think I'm doing something wrong in the way i'm instantiating my objects. Primarily because I'm not sure i understand basic best practices to write constructors.
Maybe I the desired behavior should be implemented through events, where the Test and Literal classes subscribe to changes in the Expression() and Value() methods (or rather to what calculates them). But I never used events and I'd like to know if this fundamentally can be acheived without them first.
My question: How do I make the Expression() Value() at the bottom level class "Fire up" whenever LogicStatement is instantiated, and then have the Expression and Value properties be assigned accordingly as a result.
In other words, I want the following to always be true:
test[i].Expression == literal[i].Expression == LogicStatement[i].Expression()
I'm a beginner in OOP. So any fundamental explanation is welcome.
As you are new to object oriented programming I would start with the basics and leave factories and adhering with Dependency Inversion and the interfaces away for later.
You could tell Dapper to split joined tables into multiple entities (see https://www.learndapper.com/relationships), but for learning OOP I would start doing everything manually.
Your class design does not look proper to me yet. Not sure what Expression and Value of the LogicStatement are, but if they are calculations based on the other properties, I would implement them as (just to show off with complicated words) lazy initialized cached getter properties that are invalidated in the setters of the relevant properties. That ensures you only calculate them once for as many reads you like but recalculate them on first read after one or multiple properties have been updated.
public class LogicStatement {
private string _testLogic;
private string _compareLogic;
private string _operator;
private string? _expression;
private bool? _value;
public LogicStatement(string testLogic, string compareLogic, string #operator) {
_testLogic = testLogic;
_compareLogic = compareLogic;
_operator = #operator;
}
public string TestLogic {
get {
return _testLogic;
}
set {
_testLogic = value;
InvalidateCachedValues();
}
}
public string CompareLogic {
get {
return _compareLogic;
}
set {
_compareLogic = value;
InvalidateCachedValues();
}
}
public string Operator {
get {
return _operator;
}
set {
_operator = value;
InvalidateCachedValues();
}
}
public string Expression {
get {
string? result = _expression;
if (result is null) {
_expression = result = BuildExpression();
}
return result;
}
}
public bool Value {
get {
bool? result = _value;
if (result is null) {
_value = result = EvaluateValue();
}
return result.Value;
}
}
private void InvalidateCachedValues() {
_expression = null;
_value = null;
}
private string BuildExpression() {
//Your logic goes here
throw new NotImplementedException();
}
private bool EvaluateValue() {
//Your logic goes here
throw new NotImplementedException();
}
}
Sorry, it got a bit bigger with the full properties.
In the other classes I would not copy the Value and the Expression but simply remove these properties as anybody can easily access them through the LogicStatement property:
public class Test {
public Test(int testId, int literalId, string testName, string testText, string testDisplayName, LogicStatement logicStatement) {
TestId = testId;
LiteralId = literalId;
TestText = testText;
TestDisplayName = testDisplayName;
LogicStatement = logicStatement;
}
public int TestId { get; }
public int LiteralId { get; }
public string TestName { get; }
public string TestText { get; }
public string TestDisplayName { get; }
public LogicStatement LogicStatement { get; }
}
and the Literal could look like this (I got a bit confused whether this class has one Test or a list of them, I stick to your constructor + properties that hint in the direction of a single one):
public class Literal {
private Test _test;
public Literal(string property1, int property2, Test test) {
Property1 = property1;
Property2 = property2;
_test = test;
}
public string Property1 { get; }
public int Property2 { get; }
public string Expression => _test.LogicStatement.Expression;
public bool Value => _test.LogicStatement.Value;
}
As you decided not to expose the Test in the Literal it makes sense to provide Expression and Value, otherwise they could also be removed (or kept for convenience).

Replace the object type by common data types - Type safety

I am developping a system that deals with many modules, which all have their own sets of parameters. Each parameter value can be of a common data type (string, int, long, bytes, bool).
For simplicty, a parameter object has been defined as per:
public class Parameter : IParameter
{
public string Name { get; set; }
public object Value { get; set; }
public string ValueType { get; set; }
}
Now, note that the parameter Value is declared using the type "object". The problem with that is that we loose the type safety that validates that a type is correct when assigning a value to a variable. Say the "Value" is an "int" and we were to set it to a bool, VS will complain pre and post compilation.
Now I was wondering if I could declare all the variantes of "Value" in this sorts of way:
public int IIntInterface.Value { get; set; }
public string IStringInterface.Value { get; set; }
public bool IBoolInterface.Value { get; set; }
But then, when assigning a number/string to the property "Value", "ValueType" is first checked to validate the value so that an error is flagged when the wrong type is used for that parameter?
Essentially, I am trying to get type safety support for the "object" type :-)
------------- Update ------------
I tried to keep it simple, but it seems I should clarify something.
On the client side, we end up with a List of IParameters. This list is compiled by doing something of the sort:
IPamameter a = new Parameter { Value = IntVal };
IPamameter b = new Parameter { Value = BoolVal };
var listParams = new Parameters();
listParams.Add(a);
listParams.Add(b);
Now, I tried to use generics, but it did not quite work as the type for Parameter cannot really be generic (I think):
class Program
{
static void Main(string[] args)
{
int IntVal = 10;
bool BoolVal = false;
var a = new Parameter<int> { Value = IntVal };
var b = new Parameter<bool> { Value = BoolVal };
var listParams = new Parameters<T>(); // This does not work, it has to be an actual type, but I want all the params in the same list
listParams.Add(a);
listParams.Add(b);
}
}
public class Parameter<T> : IParameter<T>
{
public string Name { get; set; }
public string ValueType { get; set; }
public T Value { get; set; }
}
public class Parameters<T> : List<IParameter<T>>
{
}
public interface IParameter<T>
{
string Name { get; set; }
string ValueType { get; set; }
T Value { get; set; }
}
In order to store heterogenous parameters in the same list IParameter would need to stay non generic, and would have no type safety on the Value property:
public interface IParameter
{
string Name{get;}
string ValueType{get;}
object Value{get;}
}
But, you could provide a generic implementation which enforces type safety on the Value and explicitly implements the Interfaces version, just returning the generic one.
public class Parameter<T> : IParameter
{
public string Name{get;set;}
public T Value {get;set;}
public string ValueType {get => typeof(T).Name;}
object IParameter.Value {get => this.Value;}
}
This would allow your client code to ensure the right types are set to the right parameters, for example:
var intParam = new Parameter<int>{Value = 10};
var strParam = new Parameter<string>{Value = "Hello World"};
var list = new List<IParameter>();
list.Add(intParam);
list.Add(strParam);
This would fail at compile time:
var badParam = new Parameter<int>{Value="Hello World"}; // Cannot implicitly convert type 'string' to 'int'
Here is a live working example: https://dotnetfiddle.net/QSAUFR
The usefulness of this code is somewhat questionable. But it's perhaps a start. I fear you'll end up in generic hell quicker than you think!

How to force to change some method when new property is added to class

I have the following issue
Here is third party class which we are used(so i cannot change it)
public class ThirdPartyEmployee
{
public string F_Name { get; set; }
public string L_Name { get; set; }
public DateTime Date_of_birth { get; set; }
public string Telephone1 { get; set; }
public string Telephone2 { get; set; }
public string Position { get; set; }
//..... and so on
}
Also we have our own smaller and better Employee class
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MobileTelephone { get; set; }
}
Sometimes we need to convert third party class to our own. There is extension method for it
public static class ThirdPartyExtensions
{
public static Employee ConvertTo(this ThirdPartyEmployee thirdPartyEmployee)
{
var result = new Employee();
result.FirstName = thirdPartyEmployee.F_Name;
result.LastName = thirdPartyEmployee.L_Name;
result.MobileTelephone = thirdPartyEmployee.Telephone1;
return result;
}
}
Now about the issue. If somebody consider to add some other properties to Employee class he\she can forget to change ConvertTo method. How we can avoid it ? Ideally i would like to have some compilation errors ...
Any suggestions ?
If your Employee class is just a container, there's one simple approach:
public class Employee
{
private readonly string firstName;
public Employee(string firstName)
{
this.firstName = firstName;
}
}
Now your conversion method has no choice but to pass all the arguments, so you get a compiler error when the conversion method isn't updated.
Of course, this still isn't foolproof - if you also care about changing the arguments, this doesn't help much.
And now that we have Roslyn, with great integration in Visual Studio, you can actually make your own compiler errors using a Roslyn analyzer. If you're not afraid of getting your hands dirty, this would be a great opportunity to show how useful something like that can be. Sadly, it's not very easy to use right now, and needs "the right kind of thinking" to be wielded well. It will allow you to make rules like "a class conversion extension method must assign all properties in the resulting class", for example.
You can not create a compilation error with standard means. There may be Visual Studio plugins that allow you to do that.
But it may not be necessary: You could change the CopyTo method so that instead of hardcoding all the properties to be copied, it uses reflection to obtain a list of all public properties to copy.
Example code to start with:
FieldInfo[] myObjectFields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo fi in myObjectFields)
{
i.SetValue(destination, fi.GetValue(source));
}
To handle different property names: You could introduce an attribute which allows you to specify which property of ThirdPartyEmployee translates to which property of Employee. This can also be evaluated using reflection.
Example:
public class Employee
{
[CopyFromThirdPartyEmployee("F_Name")]
public string FirstName { get; set; }
[CopyFromThirdPartyEmployee("L_Name")]
public string LastName { get; set; }
[CopyFromThirdPartyEmployee("Telephone1")]
public string MobileTelephone { get; set; }
}
You could have the CopyTo method throw an exception when it finds a public property which does not have the required mapping attribute. That way you could be sure that every property also has the attribute - but that would be a runtime error, not a compile time error.
Another approach be to simply make Employee a wrapper for ThirdPartyEmployee:
public class Employee
{
private ThirdPartyEmployee _baseEmployee;
public Employee() { _baseEmployee = new ThirdPartyEmployee(); }
public Employee(ThirdPartyEmployee e) { _baseEmployee = e; }
public string FirstName
{
get { return _baseEmployee.F_Name; }
set { _baseEmployee.F_Name = value; }
}
...
}
That way you'd notice that if you can't access a property you haven't implemented it. The downside is that every employee would then be based on a ThirdPartyEmployee.
You can do this with the help of reflection, but dictionary for names mapping is needed:
public static class ThirdPartyExtensions
{
static Dictionary<string, string> map;
static ThirdPartyExtensions()
{
map = new Dictionary<string, string>{ {"F_Name", "FirstName"} /*and others*/};
}
public static Employee ConvertTo(this ThirdPartyEmployee thirdPartyEmployee)
{
var result = new Employee();
if(map.Count < typeof(Employee).GetProperties().Count())
throw new Exception("Forget to add mapping for new field!");
foreach(var prop in typeof(ThirdPartyEmployee).GetProperties())
if(map.ContainsKey(prop.Name))
{
var temp = typeof(Employee).GetProperty(map[prop.Name]);
temp.SetValue(result, prop.GetValue(thirdPartyEmployee));
}
return result;
}
}
Using Roslyn analyzers it's possible to produce compile-time (and IntelliSense) errors that go beyond the scope of the compiler. Here's a very simple implementation of an analyzer that checks that all the properties of a type returned by a method have been assigned. It doesn't take into account control flow (e.g. if).
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AssignAllPropertiesAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor("AssignAllPropertiesAnalyzer",
"All properties must be assigned.", "All properties of the return type must be assigned.", "Correctness",
DiagnosticSeverity.Warning, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.MethodDeclaration);
}
private static void AnalyzeMethod(SyntaxNodeAnalysisContext context)
{
var methodNode = (MethodDeclarationSyntax)context.Node;
var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodNode);
if (methodSymbol.GetReturnTypeAttributes().Any(x => x.AttributeClass.Name == "AssignAllPropertiesAttribute"))
{
var properties = methodSymbol.ReturnType.GetMembers().OfType<IPropertySymbol>().Where(x => !x.IsReadOnly).ToList();
foreach (var assignmentNode in methodNode.DescendantNodes().OfType<AssignmentExpressionSyntax>())
{
var propertySymbol = context.SemanticModel.GetSymbolInfo(assignmentNode.Left).Symbol as IPropertySymbol;
if (propertySymbol != null)
{
properties.Remove(propertySymbol);
}
}
if (properties.Count > 0)
{
var diagnostic = Diagnostic.Create(Rule, methodSymbol.Locations[0]);
context.ReportDiagnostic(diagnostic);
}
}
}
The analyzer assumes an attribute named AssignAllProperties is applied to return type of a method. In the following example, ~~~~~~ marks the location where analyzer would produce a diagnostic.
class A
{
public string S { get; set; }
}
[return: AssignAllProperties]
public static A Create()
~~~~~~
{
return new A();
}
An analyzer can be installed both as a VSIX and as a NuGet package. I would recommend always using the NuGet approach - it would apply the analyzer for everyone consuming the code and would allow you to change the severity (e.g. to error), thus failing the compilation. To get started with building an analyzer library, install the Roslyn SDK and create an Analyzer with Code Fix C# project.
You cannot generate a compile error for that, but... I would move the conversion method to the Employee class. I suggest to avoid Extension methods that are dependend on data (like properties from other classes)
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MobileTelephone { get; set; }
public static Employee From(ThirdPartyEmployee employee)
{
var result = new Employee();
result.FirstName = thirdPartyEmployee.F_Name;
result.LastName = thirdPartyEmployee.L_Name;
result.MobileTelephone = thirdPartyEmployee.Telephone1;
return result;
}
}
This way you keep all functionality in the right class/file and it is clear for others if they add properties.

Generic class check which properties were initialized

Is there a way how I can check from an instantiated class which properties were initially set?
As you can see in the example I can check for "null" value of string data type but I can't check for int value since default value is "0".
Is there a way how I can check if a property was set at "instantiation-time" of the object?
I would like to be able to pass any class to the "ParseProperties" class.
Check this example:
class Program
{
static void Main(string[] args)
{
// The following foreach gives me the output as follows
// Actual output:
// Id
// Name
// Age
//
// Desired output:
// John
foreach (string initiatedPropery in ParseProperties(new Person { Name = "John" }))
{
Console.WriteLine(initiatedPropery);
}
// The following foreach gives me the output as follows
// Actual output:
// Id
// Age
//
// Desired output:
// Id
foreach (string initiatedPropery in ParseProperties(new Person { Id = 45 }))
{
Console.WriteLine(initiatedPropery);
}
Console.ReadLine();
}
private static List<string> ParseProperties<T>(T obj)
{
var initiatedProperties = new List<string>();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
// For strings I can check if property is null but I can't check for int's if they were set. How could I do that?
var value = typeof(T).GetProperty(property.Name).GetValue(obj, null);
if (value != null) // --> I would need to get somehow if a property was initially set or not
{
initiatedProperties.Add(property.Name);
}
}
return initiatedProperties;
}
private class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
Given a class like this:
private class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
There is really no way to handle this in general that doesn't involve some changes to the class itself. The best you could do without changing the class you are using as the generic type parameter would be something like comparing to myProp == default(S), where S is the type of the property. This would tell you that the property might not have be initialized.
If you can change the classes that are being passed as generic parameters, then you have a lot more options. The simplest would be:
public int? Age { get; set; }
Now the Age property will be null rather than 0.
Another strategy would be to have another property that will tell you if Age was set:
public bool AgeWasSet { get; private set; }
private int _age;
public int Age
{
get { return _age; }
set { _age = value; AgeWasSet = true; }
}
And you could use some convention like propNameWasSet as a property to identify which property is related to which (this isn't unheard of, JSON.Net for example will look for properties with the name ShouldSerializepropName as a way to inject some logic into serialization).
Finally, you could do something like have a base class or an interface that defines a method to give you the information you need. Something like:
public interface IFieldInitializationInfo
{
string[] GetUninitializedFields(); // or maybe PropertyInfo[]
}
And then your classes can implement that interface and report what fields haven't be initialized according to whatever logic you want to use for that particular class.
Is there a way how I can check if a property was set at "instantiation-time" of the object?
Disregarding the use of int? versus int for a "uninitialized" integer, there is no way to tell if values were set in an initializer. An initializer is the equivalent of setting the properties after construction, so
Person p = new Person() {Id = 4};
is exactly the same as
Person p = new Person();
p.Id = 4;
If you require certain properties to be set when the object is constructed, then use a constructor:
public Person(int id)
{
Id = id;
}

System.Reflection.TargetException on employee.GetType().GetProperty(property.Name)

I have come upon an issue I can't seem to figure out. I'm sure there's a simple explanation to this, but I don't understand why I get a System.Reflection.TargetException: 'Object does not match target type' when I try to get a property from (in this case) the employee object.
employee.GetType().GetProperty(property.Name)
Searching for the error returns many results describing problems with calling the Set/GetValue methods, but I haven't found a solution to this one.
I've set a breakpoint where the exception is thrown and it shows that property.Name is indeed a value - and a real property of the object. I've also tried manually specifying a property I know exists. Still the same.
Any suggestions?
EDIT: Tried the following instead:
Type type = typeof (Employee); //Throws the TargetException
PropertyInfo theProperty = type.GetProperty(property.Name);
And now the same exception is thrown at the first line above instead.
EDIT: Added code and more details about the application I'm building.
Class definition for Employee (to simplify mapping to the JSON data this class "represents", the class/fields are in Norwegian - which is the format/language the data comes in, sorry :-).)
"Ansatt" = Employee. "Ansattnummer" = EmployeeNo.
[JsonObject]
public class Ansatt
{
public int Ansattnummer { get; set; }
public string Fornavn { get; set; }
public string Etternavn { get; set; }
public int Pin { get; set; }
public string Adresse { get; set; }
public int Postnummer { get; set; }
public string Poststed { get; set; }
public int TlfPrivat { get; set; }
public int MobilTlf { get; set; }
public string EpostAdresse { get; set; }
public DateTime Fodt { get; set; }
}
My application retrieves a given dataset from a web service - it could be employees, projects or a few other possible datasets. What data to fetch is determined at runtime - by the user. The user can also specify via URL-query which portions, e.g. columns, of the dataset he/she wants. The program then creates a csv-file with the selected data.
Here's the code I use for this:
if (records != null && records.Count != 0) //records contains the chosen dataset - in this case Employees (Ansatt).
{
if (records.GetType() == typeof (List<Ansatt>))
{
foreach (var model in records as List<Ansatt>)
{
var temp = new Ansatt();
foreach (var property in model.GetType().GetProperties())
{
var currentProperty = model.GetType().GetProperty(property.Name);
if (currentProperty != null)
{
Type type = typeof (Ansatt); //Throws System.Reflection.TargetException: 'Object does not match target type'
PropertyInfo tempProperty = type.GetProperty(property.Name);
tempProperty.SetValue(temp, currentProperty.GetValue(property.Name));
}
}
csv.WriteRecord(temp);
}
}
}
You need to specify the name of the property
PropertyInfo value = employee.GetType().GetProperty("Name");
As MSDN goes, you should use it this way:
class MyClass {
private int myProperty;
// Declare MyProperty.
public int MyProperty {
get {
return myProperty;
}
set {
myProperty = value;
}
}
}
public class MyTypeClass {
public static void Main(string[] args) {
try {
// Get the Type object corresponding to MyClass.
Type myType = typeof(MyClass);
// Get the PropertyInfo object by passing the property name.
PropertyInfo myPropInfo = myType.GetProperty("MyProperty");
// Display the property name.
Console.WriteLine("The {0} property exists in MyClass.", myPropInfo.Name);
// Instantiate MyClass
var myObject = new MyClass()
{
MyProperty = 5
};
// Get value using reflection
Console.WriteLine("My property value for my object is {0}.", myPropInfo.GetValue(myObject));
} catch (NullReferenceException e) {
Console.WriteLine("The property does not exist in MyClass." + e.Message);
}
}
}
For your code, when you want to get the property value of an object instance, you should pass object as reference to PropertyInfo.GetValue(object) function.
Instead of this:
tempProperty.SetValue(temp, currentProperty.GetValue(property.Name));
Do this:
tempProperty.SetValue(temp, currentProperty.GetValue(model));
For you to get the property of object through reflection, make it sure that the property name is public with getter and setter else it will return null.
Ex.
public class Employee
{
public string YouProperty { get; set; }
}
var employee = new Employee();
var result = employee.GetType().GetProperty("YouProperty");
// The result is property info
Kindly read some information here.

Categories