I am new with C# and I have some troubles with enum.
I have Enum defined like this:
public enum CustomFields
{
[Display(Name = "first_name")]
FirstName = 1,
[Display(Name = "last_name")]
LastName = 2,
}
What I need is code which will check does display name exist and if so return enum value.
So if I have display name:
var name = "first_name";
I need something like:
var name = "first_name";
CustomFields.getEnumValue(name);
This should return:
CustomFields.FirstName;
You could use generics:
public class Program
{
private static void Main(string[] args)
{
var name = "first_name";
CustomFields customFields = name.GetValueFromName<CustomFields>();
}
}
public enum CustomFields
{
[Display(Name = "first_name")]
FirstName = 1,
[Display(Name = "last_name")]
LastName = 2,
}
public static T GetValueFromName<T>(this string name) where T : Enum
{
var type = typeof(T);
foreach (var field in type.GetFields())
{
if (Attribute.GetCustomAttribute(field, typeof(DisplayAttribute)) is DisplayAttribute attribute)
{
if (attribute.Name == name)
{
return (T)field.GetValue(null);
}
}
if (field.Name == name)
{
return (T)field.GetValue(null);
}
}
throw new ArgumentOutOfRangeException(nameof(name));
}
Try the following.
void Main()
{
CustomFields value1 = GetEnumValue("first_name");
CustomFields value2 = GetEnumValue("last_name");
}
static Dictionary<string, CustomFields> displayNameMapping;
static CustomFields GetEnumValue(String displayName){
if (displayNameMapping == null){
var enumType = typeof(CustomFields);
var displayAttributeType = typeof(DisplayAttribute);
CustomFields? found = null;
displayNameMapping = new Dictionary<string, CustomFields>();
Enum.GetNames(enumType).ToList().ForEach(name=>{
var member = enumType.GetMember(name).First();
var displayAttrib = (DisplayAttribute)member.GetCustomAttributes(displayAttributeType, false).First();
displayNameMapping.Add(displayAttrib.Name, (CustomFields)Enum.Parse(enumType, name));
});
}
return displayNameMapping[displayName];
}
// Define other methods and classes here
public enum CustomFields
{
[Display(Name = "first_name")]
FirstName = 1,
[Display(Name = "last_name")]
LastName = 2,
}
Related
I am using dotConnect for MySQL product of Devart. MySQL database structure likes this:
I am getting data like this:
public int user_id { get; set; } = 2;
public string lang { get; set; } = "en"; // Depending on the situation, it may also be "tr".
private readonly mainDataContext _db = new();
var cats = _db.categories.Where(s => s.u_id == user_id);
foreach (var cat in cats)
{
MessageBox.Show(cat.name_en);
}
In the MessageBox.Show I can not use cat.name + "_" + lang like PHP. I don't know how to get over this problem.
In nutshell, you can use this:
cat.GetType().GetProperty("name_" + lang).GetValue(cat,null))
But it's better to call a method to get value:
static public T getval<T>(Object obj, string field)
{
return (T)obj.GetType().GetProperty(field).GetValue(obj, null);
}
Here is a full example:
using System;
namespace Example
{
public class user
{
public int user_id { get; set; } = 2;
public string name_en { get; set; }
public string name_tr { get; set; }
}
class Program
{
static public T getval<T>(Object obj, string field)
{
return (T)obj.GetType().GetProperty(field).GetValue(obj, null);
}
static void Main(string[] args)
{
List<user> u = new List<user>();
u.Add(new user { user_id = 1, name_en = "Foods", name_tr = "name_tr value 1" });
u.Add(new user { user_id = 2, name_en = "Pizza", name_tr = "name_tr value 2" });
u.Add(new user { user_id = 2, name_en = "Other", name_tr = "name_tr vale 3" });
var lang = "en";
var cats = u.Where(s => s.user_id == 2);
foreach (var cat in cats)
{
Console.WriteLine(getval<string>(cat,"name_"+lang));
}
return;
}
}
}
I want to get the property name and the value from object and pass them to the list.
i dont want to pass one by one property and value to the list like commented in my code. want to use loop and add name and value dynamically
public class ParametersList
{
public string Name { get; set; }
public dynamic Value { get; set; }
}
public class BookVM
{
public string AuthorName{ get; set; }
public string CoverUrl { get; set; }
public int AuthorIds { get; set; }
}
public List<Book> Addgetallbooks(BookVM BookVM)
{
List<ParametersList> obj = new List<ParametersList>();
//List<ParametersList> obj = new List<ParametersList>
//{
// new ParametersList{Name=nameof(BookVM.AuthorIds),Value=BookVM.AuthorIds},
// new ParametersList{Name=nameof(BookVM.AuthorName),Value=BookVM.AuthorName},
// new ParametersList{Name=nameof(BookVM.CoverUrl),Value=BookVM.CoverUrl}
//};
var getdata = _opr.GetBooks1(obj);
return getdata;
}
You need to use reflection, but not sure if you should do it :)
[TestMethod]
public void Foo()
{
var book = new BookVM() { AuthorIds = 1, AuthorName = "some name", CoverUrl = "some cover url" };
var result = GetParameters(book);
result.Should().BeEquivalentTo(new[]
{
new ParametersList { Name = nameof(BookVM.AuthorIds), Value = 1 },
new ParametersList() { Name = nameof(BookVM.AuthorName), Value = "some name" },
new ParametersList { Name = nameof(BookVM.CoverUrl), Value = "some cover url" }
});
}
private static List<ParametersList> GetParameters(BookVM book)
{
return typeof(BookVM).GetProperties().Select(p => new ParametersList
{
Name = p.Name, Value = p.GetValue(book)
}).ToList();
}
I have following code which is working fine . but i need to use extension method with its Enum type.
public class Dropdown
{
public Dropdown() { }
public Dropdown(int id, string name)
{
Id = id;
Name = name;
}
public Dropdown(string name)
{
Name = name;
}
public int Id { get; set; }
public string StringId { get; set; }
public string Name { get; set; }
}
public enum AccidentTypeEnum
{
[Display(Name = "Minor")]
Minor = 0,
[Display(Name = "Major")]
Major = 1,
[Display(Name = "Severe")]
Severe = 2
}
Extension Method
public static class EnumExtensions
{
public static List<Dropdown> ConvertToDropdown(this Enum mEnum)
{
var dropDownlist = new List<Dropdown>();
var enumType = mEnum.GetType();
var enumValuies = Enum.GetValues(enumType);
foreach (var singleValue in enumValuies)
{
dropDownlist.Add(new Dropdown { Id = (int)singleValue, Name = singleValue.ToString() });
}
return dropDownlist;
}
}
Question:
Above code is working fine if i call extension method using below lines
var TestAcident = AccidentTypeEnum.Major;
var resultDropdown = TestAcident.ConvertToDropdown();
But how can i call it just like below lines
var resultDropdown = AccidentTypeEnum.ConvertToDropdown(); //<-- i need to use like this. but it not working
You can do that
List<AccidentTypeEnum> types = Utils<AccidentTypeEnum>.ConvertToDropdown();
this way:
/// <summary>Pseudo extension class for enumerations</summary>
/// <typeparam name="TEnum">Enumeration type</typeparam>
public class Utils<TEnum> where TEnum : struct, IConvertible
{
public static List<Dropdown> ConvertToDropdown()
{
var enumType = typeof(TEnum);
return enumType.IsEnum
? enumType.GetEnumValues()
.OfType<TEnum>()
.Select(e => new Dropdown
{
Id = Convert.ToInt32(Enum.Parse(enumType, e.ToString()) as Enum),
Name = GetDisplay(e)
})
.ToList()
: throw new ArgumentException($"{enumType.Name} is not enum");
}
private static string GetDisplay<T>(T value)
{
var enumValueText = value.ToString();
var displayAttribute = value
.GetType()
.GetField(enumValueText)
.GetCustomAttributes(typeof(DisplayAttribute), false)
.OfType<DisplayAttribute>()
.FirstOrDefault();
return displayAttribute == null ? enumValueText : displayAttribute.Description;
}
}
I have the following situation.
I have a bunch of simple classes, for example this one
public class Student
{
public int Id { get; set; }
public int Age { get; set; }
public decimal AverageMark { get; set; }
public string Name { get; set; }
public string University { get; set; }
}
There is web page for every of them where user can create, edit and delete. When we create Student of update it, we need to validate it.
The problem is that we do not know validation rules during compilation !!!
We have separate web page for administrator where he set up validation criterias,
for example, that Student Age cannot be less then 15 or University have to be equal "SomeUniversity".
As result i have some list of criterias stored in my database
public class Criteria
{
public string PropertyName { get; set; }
public string OperationName { get; set; }
public string OperationValue { get; set; }
}
I have created simple console application for investigation purposes. Here is code
namespace DynamicValidation
{
class Program
{
static void Main(string[] args)
{
//set up students
var student1 = new Student() { Age = 20, AverageMark = 4, Name = "Ihor", University = "Lviv National University" };
var student2 = new Student() { Age = 20, AverageMark = 4, Name = "Taras", University = "Lviv National University" };
var student3 = new Student() { Age = 20, AverageMark = 5, Name = "Marko", University = "" };
var student4 = new Student() { Age = 20, AverageMark = 3, Name = "Tanya", University = "" };
var student5 = new Student() { Age = 22, AverageMark = 4, Name = "Ira", University = "" };
var students = new List<Student>() { student1, student2, student3, student4, student5 };
//set up validation rules
var criteria1 = new Criteria("Age", "Equal", "20");
var criteria2 = new Criteria("AverageMark", "NotLessThan", "4");
var criteria3 = new Criteria("University", "Contains", "Lviv");
var criterias = new List<Criteria>() { criteria1, criteria2, criteria3 };
var result = new List<Student>();
foreach (var currentStudent in students)
{
foreach (var currentCriteria in criterias)
{
object currentPropertyValue = typeof(Student).GetProperty(currentCriteria.PropertyName).GetValue(currentStudent);
//what is next ???!!!
}
}
}
}
public class Student
{
public int Id { get; set; }
public int Age { get; set; }
public decimal AverageMark { get; set; }
public string Name { get; set; }
public string University { get; set; }
}
public class Criteria
{
public string PropertyName { get; set; }
public string OperationName { get; set; }
public string OperationValue { get; set; }
}
}
How can i implement this piece of code ? (expression trees, dynamic ?)
I do not want that you do work for me but maybe there are some articles about this ? (i tried to found but without success)
Maybe some advices about approach ?
Maybe there is some similar open code ?
Or maybe it is already implemented in some libraries ?
Will be thankful for any help :)
You could write a student validator function, see IsValidStudent(Criteria criteria):
public class Student
{
public int Id { get; set; }
public int Age { get; set; }
public decimal AverageMark { get; set; }
public string Name { get; set; }
public string University { get; set; }
public bool IsValidStudent(Criteria criteria)
{
return IsValidByAge(criteria)
&& IsValidByMarks(criteria)
&& IsValidByUniversity(criteria);
}
private bool IsValidByAge(Criteria criteria)
{
switch (criteria.OperationType)
{
case Criteria.Operation.GreaterThan:
return Convert.ToInt32(criteria.OperationValue) > this.Age;
case Criteria.Operation.LessThan:
return Convert.ToInt32(criteria.OperationValue) < this.Age;
case Criteria.Operation.EqualTo:
return Convert.ToInt32(criteria.OperationValue) == this.Age;
default:
return false;
}
}
private bool IsValidByMarks(Criteria criteria)
{
// etc...
}
private bool IsValidByUniversity(Criteria criteria)
{
// etc...
}
}
Usage:
var result = new List<Student>();
foreach (var currentStudent in students)
{
foreach (var currentCriteria in criterias)
{
if (currentStudent.IsValidStudent(currentCriteria))
{
result.Add(currentStudent);
}
}
}
I also extended your Criteria class:
public class Criteria
{
public string PropertyName { get; set; }
public Operation OperationType { get; set; }
public string OperationValue { get; set; }
public enum Operation
{
EqualTo,
GreaterThan,
LessThan,
Contains
}
public Criteria(string propertyName, Operation operationType, string operationValue)
{
this.PropertyName = propertyName;
this.OperationType = operationType;
this.OperationValue = operationValue;
}
}
IMHO, I have found a little better solution then proposed
Now we do not need to change validation logic inside Student class if new property will be added. Also this code can be applied to any other class (not only for Student class as before)
Interface for validation
public interface IValidator
{
bool Validate(object value, object validateWith);
}
Set of implementations
public class ContainsValidator : IValidator
{
public bool Validate(object value, object validateWith)
{
string valueString = Convert.ToString(value);
string validateWithString = Convert.ToString(validateWith);
return valueString.Contains(validateWithString);
}
}
public class StartWithValidator : IValidator
{
public bool Validate(object value, object validateWith)
{
string valueString = Convert.ToString(value);
string validateWithString = Convert.ToString(validateWith);
return valueString.StartsWith(validateWithString);
}
}
public class LengthValidator : IValidator
{
public bool Validate(object value, object validateWith)
{
string valueString = Convert.ToString(value);
int valueLength = Convert.ToInt32(validateWith);
return (valueString.Length == valueLength);
}
}
public class LessThanValidator : IValidator
{
public bool Validate(object value, object validateWith)
{
decimal valueDecimal = Convert.ToDecimal(value);
decimal validateWithDecimal = Convert.ToDecimal(validateWith);
return (valueDecimal < validateWithDecimal);
}
}
public class MoreThanValidator : IValidator
{
public bool Validate(object value, object validateWith)
{
decimal valueDecimal = Convert.ToDecimal(value);
decimal validateWithDecimal = Convert.ToDecimal(validateWith);
return (valueDecimal > validateWithDecimal);
}
}
public class EqualValidator : IValidator
{
public bool Validate(object value, object validateWith)
{
string valueString = Convert.ToString(value);
string validateWithString = Convert.ToString(validateWith);
return (valueString == validateWithString);
}
}
And usages
class Program
{
static void Main(string[] args)
{
//set up students
var student1 = new Student() { Age = 20, AverageMark = 5, Name = "Ihor", University = "Lviv National University" };
var student2 = new Student() { Age = 20, AverageMark = 5, Name = "SomeLongName", University = "Lviv National University" };
var student3 = new Student() { Age = 20, AverageMark = 5, Name = "Taras", University = "Kyiv National University" };
var student4 = new Student() { Age = 20, AverageMark = 5, Name = "Marko", University = "Some University" };
var student5 = new Student() { Age = 20, AverageMark = 4, Name = "Tanya", University = "Lviv National University" };
var student6 = new Student() { Age = 22, AverageMark = 4, Name = "Ira", University = "" };
var students = new List<Student>() { student1, student2, student3, student4, student5, student6 };
//set up validation rules
var criteria1 = new Criteria("Age", "Equal", "20");
var criteria2 = new Criteria("AverageMark", "MoreThen", "4");
var criteria3 = new Criteria("University", "Contains", "National");
var criteria4 = new Criteria("University", "StartWith", "Lviv");
var criteria5 = new Criteria("Name", "Length", "4");
var criterias = new List<Criteria>() { criteria1, criteria2, criteria3, criteria4, criteria5 };
var result = new List<Student>();
foreach (var currentStudent in students)
{
var isValid = true;
foreach (var currentCriteria in criterias)
{
object currentPropertyValue = typeof(Student).GetProperty(currentCriteria.PropertyName).GetValue(currentStudent);
IValidator currentValidator = ValidatorFactory.GetValidator(currentCriteria.OperationName);
bool validationResult = currentValidator.Validate(currentPropertyValue, currentCriteria.OperationValue);
if (!validationResult)
{
isValid = false;
break;
}
}
if (isValid)
result.Add(currentStudent);
}
}
}
In the end the the code of ValidatorFactory
public class ValidatorFactory
{
public static IValidator GetValidator(string validatorName)
{
validatorName = validatorName.ToUpper();
switch (validatorName)
{
case "CONTAINS": return new ContainsValidator();
case "STARTWITH": return new StartWithValidator();
case "EQUAL": return new EqualValidator();
case "MORETHEN": return new MoreThanValidator();
case "LENGTH": return new LengthValidator();
default: throw new Exception("There are not appropriate validator.");
}
}
}
Maybe this will help someone in the future :)
I would like to be able to access the value of an object property to any depth having only the string-key of the property. Also, if possible, using collection indexing on List properties.
So, If I have the string "Person.Surname" then I could get the value "Smith" from and instanciated CaseConductor object. So given some setup code like this ...
//- Load a caseConductor
var caseConductor = new CaseConductor();
caseConductor.CaseID = "A00001";
// person
caseConductor.Person = new Person();
caseConductor.Person.Surname = "Smith" ;
caseConductor.Person.DOB = DateTime.Now ;
// case note list
caseConductor.CaseNoteList = new List<Note>();
caseConductor.CaseNoteList.Add(new Note { NoteText = "A-1" , NoteDt = DateTime.Now });
caseConductor.CaseNoteList.Add(new Note { NoteText = "B-2", NoteDt = DateTime.Now });
// I could do this ...
object val = caseConductor.SomeCleverFunction("Person.Surname");
// or this ...
object val = caseConductor.SomeCleverFunction("CaseNoteList[0].NoteText");
Has anyone done this before ?
Here are some setup classes ...
class Note
{
public Guid NoteID { get; set; }
public string NoteText { get; set; }
public DateTime? NoteDt { get; set; }
}
public class Person
{
public Guid PersonID { get; set; }
public string Surname { get; set; }
public string Forename { get; set; }
public DateTime? DOB { get; set; }
}
class CaseConductor
{
public String CaseID{get;set;}
public Person Person { get; set; }
public List<Note> CaseNoteList { get; set; }
}
Our use case is to iterate over a series of appropriately named content controls in a word dcoument template using open xml sdk 2, and poke values into a newly created word documents, something like this ...
List<SdtElement> ccList = wordprocessingDocument.MainDocumentPart.Document.Descendants<SdtElement>().ToList();
foreach (var cc in ccList)
{
string alias = cc.SdtProperties.GetFirstChild<SdtAlias>().Val.Value;
switch (cc.GetType().Name)
{
case "SdtRun":
SdtRun thisRun = (SdtRun)cc;
//thisRun.Descendants<Text>().First().Text = theValueToBePoked ;
break;
}
}
Use good old reflection. I have tested and this actually works:
public static object GetValue(object o, string propertyName)
{
Type type = o.GetType();
PropertyInfo propertyInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance ).Where(x => x.Name == propertyName).FirstOrDefault();
if(propertyInfo!=null)
{
return propertyInfo.GetValue(o, BindingFlags.Instance, null, null, null);
}
else
{
return null; // or throw exception
}
}
I'm assuming that
caseConductor.SomeCleverFunction
is not a static method, and has access to the Person object, and that the Person object itself if a public property.
I'm also assuming that you want to pass a string like "prop.address.street" where each sub property is an class that containts a puplic property with that name
Split the string input on the period, find the left most string
Use reflection to get a list of properties ( typeof(caseconductor).GetProperties() )
Find the matching property, call GetValue on it, passing the last known solid object (starting with 'this') and storing a refernce to it.
if there is more sub properties in the string left, repeat to step 1, removing the left most part of the string.
otherwise, call GetValue() on the property, using the last GetValue() return object from step 3, and return it.
Something like:
"prop.address.street" -> find property "prop" from 'this' and GetValue,
there is still more "."'s so repeat, storing return value
"address.street" -> find property "address" from the last returned GetValue, and get it's value.
there is still more "."'s so repeat, storing return value
"street" -> find property "street" from the last returned GetValue, and return it's value.
End of string, return last value
Edit -
This is pretty rough, but toss it into LinqPAD and take a look.
http://www.linqpad.net/
Edit #2 - you should be able to index into arrays using the ^ syntax below.
Again this is reaaaaaaaaally rough, just enough to get a working example.
Edit #3 - Cleaned up the example slightly and changed it from my example classes to yours.
void Main()
{
//- Load a caseConductor
var caseConductor = new CaseConductor();
caseConductor.CaseID = "A00001";
// person
caseConductor.Person = new Person();
caseConductor.Person.Surname = "Smith" ;
caseConductor.Person.DOB = DateTime.Now ;
// case note list
caseConductor.CaseNoteList = new List<Note>();
caseConductor.CaseNoteList.Add(new Note { NoteText = "A-1" , NoteDt = DateTime.Now });
caseConductor.CaseNoteList.Add(new Note { NoteText = "B-2", NoteDt = DateTime.Now });
// I could do this ...
string val1 = caseConductor.GetPropertyValue<string>("Person.Surname");
// or this ...
Note val2 = caseConductor.GetPropertyValue<Note>("CaseNoteList^1");
val1.Dump("val1"); //this is a string
val2.Dump("val2"); //this is a Note
}
public static class extensions
{
public static T GetPropertyValue<T>(this object o,string Properties) where T:class
{
var properties = Properties.Split('.');
var indexsplit = properties[0].Split('^');
var current = indexsplit[0];
var prop = (from p in o.GetType().GetProperties() where p.Name == current select p).Take(1).Single();
var val = prop.GetValue(o,null);
if(indexsplit.Length>1)
{
var index = int.Parse(indexsplit[1]);
IList ival = (IList)val;
val = ival[index];
}
if(properties[0] == Properties)
return (T)val;
else
return val.GetPropertyValue<T>(Properties.Replace(properties[0]+".",""));
}
}
class Note
{
public Guid NoteID { get; set; }
public string NoteText { get; set; }
public DateTime? NoteDt { get; set; }
}
public class Person
{
public Guid PersonID { get; set; }
public string Surname { get; set; }
public string Forename { get; set; }
public DateTime? DOB { get; set; }
}
class CaseConductor
{
public String CaseID{get;set;}
public Person Person { get; set; }
public List<Note> CaseNoteList { get; set; }
}
OK, I came up with something which continues Aliosted and asowyer start suggestions, here it is. You can see I still having trouble with the index access of composed objects. Thnaks for your help.
#region object data ...
var model = new HcmlDocumentProductionModel();
model.CaseID = "A001";
model.CaseConductor = new CaseConductor();
model.CaseConductor.AField = "AField";
model.CaseConductor.Person = new Person();
model.CaseConductor.Person.Surname = "{Smith}";
model.CaseConductor.Person.DOB = DateTime.Now;
model.CaseConductor.CaseNoteList = new List<Note>();
model.CaseConductor.CaseNoteList.Add(new Note { NoteText = "A-1", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.CaseNote });
model.CaseConductor.CaseNoteList.Add(new Note { NoteText = "B-2", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.ReferralNote });
model.CaseConductor.CaseNoteList.Add(new Note { NoteText = "C-3", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.StatusNote });
model.CaseConductor.CaseNoteList.Add(new Note { NoteText = "d-3", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.CaseNote });
model.CaseConductor.CaseNoteList.Add(new Note { NoteText = "e-3", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.StatusNote });
model.CaseConductor.CaseNoteList.Add(new Note { NoteText = "f-3", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.CaseNote });
#endregion
string head = "";
string tail = "";
// tail
tail = "".Tail();
tail = "Surname".Tail();
tail = "Person.Surname".Tail();
tail = "CaseConductor.Person.Surname".Tail();
// head
head = "".Head();
head = "Surname".Head();
head = "Person.Surname".Head();
head = "CaseConductor.Person.Surname".Head();
// ObjectDictionary
//var person = new Person { Surname = "Smith" };
//var d = person.ObjectDictionary();
//object ovalue = d["Surname"];
// get value special
object o2 = model.CaseConductor.Person.ValueByKey("Surname");
object o3 = model.CaseConductor.Person.ValueByKey("DOB");
object o4 = model.CaseConductor.ValueByKey("Person.Surname");
object o5 = model.ValueByKey("CaseConductor.Person.Surname");
// get the list of ...
object o6 = model.ValueByKey("CaseConductor.CaseNoteList");
// get item - index thing does not work - get anull here
string noteText = model.CaseConductor.CaseNoteList[1].NoteText;
object o7 = model.ValueByKey("CaseConductor.CaseNoteList[1].NoteText");
namespace Zed
{
public static class Zed
{
public static object ValueByKey(this object o, string key)
{
if (!String.IsNullOrEmpty(key))
{
if (!key.Contains("."))
{
return (o.ObjectDictionary())[key];
}
else
{
// key contains a dot ; therefore get object by the name of the head
// and pass on that object and get propety by the tail
var d = o.ObjectDictionary();
var head = key.Head();
if (head.Contains("["))
{
string headMinusIndexer = head.Substring(0, head.IndexOf("["));
string indexString = head.Between("[", "]");
int index = Convert.ToInt32(indexString);
object oArray = d[headMinusIndexer];
//List<object> oList= d[headMinusIndexer];
// now get the object with the index, ... and continue
//object el = ((object[])oArray)[index];
return null;
}
else
{
var onext = d[head];
return onext.ValueByKey(key.Tail());
}
}
}
return null;
}
public static Dictionary<string,object> ObjectDictionary(this object o)
{
return o.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(o, null));
}
public static string Head(this string key)
{
var head = String.Empty;
var splittBy = '.';
if (!String.IsNullOrEmpty(key))
{
var keyArray = key.Split(splittBy);
head = keyArray[0];
}
//-Return
return head;
}
public static string Tail(this string key)
{
var tail = "";
var splittBy = '.';
if (!String.IsNullOrEmpty(key))
{
var keyArray = key.Split(splittBy);
for (int i = 1; i < keyArray.Length; i++)
{
tail += (i > 1) ? "." + keyArray[i] : keyArray[i];
}
}
//-Return
return tail;
}
public static string Between(this string head, string start, string end)
{
string between = String.Empty ;
between = head.Substring(head.IndexOf(start) + 1, head.IndexOf(end) - head.IndexOf(start) - 1);
return between;
}
public static object ZGetValue( this object o, string propertyName)
{
Type type = o.GetType();
PropertyInfo propertyInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == propertyName).FirstOrDefault();
if (propertyInfo != null)
{
return propertyInfo.GetValue(o, BindingFlags.Instance, null, null, null);
}
else
{
return null;
}
}
}
}