C# | Linq | SubSonic - Class object - c#

I have this class/object below:
public class Person
{
public string FirstName;
public string MI;
public string LastName;
}
Person p=new Person();
p.FirstName = "Jeff";
p.MI = "A";
p.LastName = "Price";
Is there any built in in linq or c# or in subsonic that will create an output of this?:
string myString = "FirstName=\"Jeff\" p.MI=\"A\" p.LastName=\"Price\"";

It seems you need a ToString overload in Person. Also, don't expose public fields like that. Use properties.
public class Person
{
public string FirstName { get; set; }
public string MI { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return "FirstName=\"" + FirstName + "\" p.MI=\"" + MI + "\" p.LastName=\"" + LastName + "\"";
}
}
(edit)
Here's your request (but it requires properties):
public static class ObjectPrettyPrint
{
public static string ToString(object obj)
{
Type type = obj.GetType();
PropertyInfo[] props = type.GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var prop in props)
{
sb.Append(prop.Name);
sb.Append("=\"");
sb.Append(prop.GetValue(obj, null));
sb.Append("\" ");
}
return sb.ToString();
}
}
Usage:
Console.WriteLine(ObjectPrettyPrint.ToString(new Person { FirstName, = "A", MI = "B", LastName = "C" }));

Well, as for LINQ and C#, not by default.
However, in the Person class you can override the ToString() event to do it for you.
public override string ToString()
{
return string.Format("p.Firstname={0} p.MI={1} p.LastName={2}", FirstName, MI, LastName);
}
And then you would just call it as follows:
string myString = p.ToString();
Which will give you the output you are looking for.

Related

dynamic to concrete type with automapper

I do a post with an anonymous type on an WebApi controller in the body I have this new { Firstname = "AA", Lastname = "BB"}
[HttpPost]
public IHttpActionResult Post([FromBody]dynamic person)
{
}
When I hit the controller, person is not null and I can see the the properties with their data.
In the controller I'd like convert the dynamic type to my concrete type Person
public class Person
{
public string Firstname { get; set; }
public string Lastname { get; set; }
}
I tried with Mapper.Initialize(cfg => cfg.CreateMap<dynamic, Person>());
When I do this
var person = Mapper.Map<dynamic, Person>(source);
All the properties of person are null.
Any idea ?
Thanks,
According to the documentation, instead of...
var person = Mapper.Map<dynamic, Person>(source);
...just use...
var person = Mapper.Map<Person>(source);
Full example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString() { return FirstName + " " + LastName; }
}
//Main
Mapper.Initialize( cfg => {} );
dynamic source = new ExpandoObject();
source.FirstName = "Hello";
source.LastName = "World";
var person = Mapper.Map<Person>(source);
Console.WriteLine("GetType()= '{0}' ToString()= '{1}'", person.GetType().Name, person);
Output:
GetType()= 'Person' ToString()= 'Hello World'
Link to DotNetFiddle demo

How to access a property of a class by its name?

I find it hard to clearly describe the case in a one-sentence title. Here is the example:
public class Person
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public enum PersonProperties
{
FirstName = 1,
MiddleName = 2,
LastName = 3
}
I am hoping to do this:
foreach (var p in Persons) {
var nameCollection=new List<string>();
foreach (var s in (SectionsEnum[]) Enum.GetValues(typeof (SectionsEnum)))
{
nameCollection.Add(p.GetPropertyByName(s);
}
}
Now, how can we implement the GetPropertyByName() part?
You could do this directly using reflection:
public string GetPropertyByName(SectionsEnum s)
{
var property = typeof(Person).GetProperty(s.ToString());
return (string)property.GetValue(this);
}
Or maybe with a switch.
public string GetPropertyByName(SectionsEnum s)
{
switch (s)
{
case SectionsEnum.FirstName:
return this.FirstName;
case SectionsEnum.MiddleName:
return this.MiddleName;
case SectionsEnum.LastName:
return this.LastName;
default:
throw new Exception();
}
}
But I'd ask if you wouldn't be better served by a wholly different approach, e.g. a list:
public IList<string> NameProperties
{
get
{
return new[] { FirstName, MiddleName, LastName };
}
}
Or instead of having SectionsEnum, use Funcs:
//was
SectionsEnum s = SectionsEnum.FirstName;
//instead
Func<Person, string> nameFunc = p => p.FirstName;
string name = nameFunc(myPerson);
this should be a good starting point for you
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Person p = new Person() { FirstName ="a", MiddleName = "b", LastName = "c" };
List<string> result = new List<string>();
string[] enums = Enum.GetNames(typeof(PersonProperties));
foreach(string e in enums)
{
result.Add(p.GetType().GetProperty(e).GetValue(p, null).ToString());
}
int i = 0;
foreach (string e in enums)
{
Console.WriteLine(string.Format("{0} : {1}", e, result[i++]));
}
Console.ReadKey(false);
}
}
public class Person
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public enum PersonProperties
{
FirstName = 1,
MiddleName = 2,
LastName = 3
}
}

C# Reference a property through a string returned from the Console.ReadLine

I'm new to C# and slowly learning as I go forward.
In a console application I want to be able to type in the name of the property I want to display. The problem I stumble upon is that ReadLine will return a string and I do not know how to turn that string in to a reference to the actual property.
I wrote a simple example to explain what I'm trying to do.
The example will now only type out whatever input it gets twice.
I have tried typeof(Person).GetProperty(property).GetValue().ToString() but all I get is an error message saying that there is no overload for GetValue that takes 0 arguments.
Thanks
Rickard
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace AskingForHelp1
{
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.FirstName = "Mike";
p.LastName = "Smith";
p.Age = 33;
p.displayInfo(Console.ReadLine());
}
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public UInt16 Age { get; set; }
public Person()
{
FirstName = "";
LastName = "";
Age = 0;
}
public void displayInfo(string property)
{
Console.WriteLine(property + ": " + property);
Console.ReadKey();
}
}
}
You should use smth like this:
public static object GetPropValue( object src, string propName )
{
return src.GetType( ).GetProperty( propName ).GetValue( src, null );
}
As second parameter is an index:
index
Type: System.Object[]
Optional index values for indexed properties. This value should be null for non-indexed properties.
This will give you what you are looking for.
static void Main(string[] args)
{
Person p = new Person();
p.FirstName = "Mike";
p.LastName = "Smith";
p.Age = 33;
Console.WriteLine("List of properties in the Person class");
foreach (var pInfo in typeof (Person).GetProperties())
{
Console.WriteLine("\t"+ pInfo.Name);
}
Console.WriteLine("Type in name of property for which you want to get the value and press enter.");
var property = Console.ReadLine();
p.displayInfo(property);
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public UInt16 Age { get; set; }
public Person()
{
FirstName = "";
LastName = "";
Age = 0;
}
public void displayInfo(string property)
{
// Note this will throw an exception if property is null
Console.WriteLine(property + ": " + this.GetType().GetProperty(property).GetValue(this, null));
Console.ReadKey();
}
}
GetValue needs an instance of your class to actually get value from. Like this:
typeof(Person).GetProperty(property).GetValue(this).ToString()
// to be used in a non-static method of Person
you need to give the GetValue function the reference of the object that contains the property.
you need to change your displayInfo function:
public void displayInfo(string property, Person p)
then in this function you can call the GetValue function

Why aren't my values passed to the properties of my class?

So I have a class:
public class Person
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public Person()
{
AddPerson();
}
private void AddPerson()
{
string fn = this.Firstname;
string ln = this.Lastname;
// Do something with these values
// Probably involves adding to a database
}
}
And I have some code that will instantiate an object and add it to the database, returning the the object of type Person:
Person me = new Person()
{
Firstname = "Piers",
Lastname = "Karsenbarg"
};
However, when I debug this, and get to the AddPerson() method, the properties this.Firstname and this.Lastname don't have anything in them (in this case are empty).
Where am I going wrong?
This is because properties are assigned after constructor is called. Basicaly, this:
Person me = new Person()
{
Firstname = "Piers",
Lastname = "Karsenbarg"
};
is the same as:
Person me = new Person();
me.Firstname = "Piers";
me.Lastname = "Karsenbarg";
Only difference here is syntax. In your case you may want to pass those variables via parametrized constructor (new Person("Piers", "Karsenbarg")).
You have not assigned any values to your properties. I would suggest passing in the names you want in the constructor:
public class Person
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public Person(string firstname, lastname)
{
this.Firstname = firstname;
this.Lastname = lastname;
AddPerson();
}
private void AddPerson()
{
string fn = this.Firstname;
string ln = this.Lastname;
// Do something with these values
// Probably involves adding to a database
}
}
A person cannot exist without a firstname or lastname so this makes logical sense

Can we create a dictionary with in a list in C#?

I have to create a list as follows :
name, roll no
subjectno, subject type
subject no, subject type
e.g.
name[0] = ron, roll no[0] = 12
subjectno[0]=1, subject type[0]="english"
subjectno[1]=12, subject type[1]="maths"
name[1] = elis, roll no[1] = 11
subjectno[0]=1, subject type[0]="english"
subjectno[1]=12, subject type[1]="maths"
subjectno[2]=14, subject type[2]="physics"
I am not sure how to do this in C#.
I tried making a list of student info and then for subject no and subject type i tried to make a dictionary.
I have written the code like this -
class Student
{
public class StudentInfo
{
public String name { get; set; }
public int rollno { get; set; }
Dictionary<String, String> subjects;
public StudentInfo(String name, int rollno)
{
this.name = name;
this.rollno = rollno;
}
public void addstudentinfo(string subjectno, string subjecttype)
{
if (subjects == null)
subjects = new Dictionary<string, string>();
subjects.Add(subjectno, subjecttype);
}
}
Here how I would do. First create these two class
public class Student
{
public int RollNo { get; set; }
public string Name { get; set; }
public Student(int rNo, string name)
{
this.RollNo = rNo;
this.Name = name;
}
public Student()
{
}
}
public class Subject
{
public int SubjectNo { get; set; }
public string Type { get; set; }
public Subject(int sNo, string sType)
{
this.SubjectNo = sNo;
this.Type = sType;
}
public Subject()
{
}
}
Then fill in the objects as follows :-
Dictionary<Student, List<Subject>> studentLists = new Dictionary<Student, List<Subject>>();
Student std = new Student() { RollNo = 11, Name = "John" };
List<Subject> sbj = new List<Subject>() {new Subject(020, "Math"),new Subject(030,"English") };
studentLists.Add(std, sbj);
Then iterate thru the Dictionary as follows:-
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<Student, List<Subject>> item in studentLists)
{
sb.Append("Student No : " + item.Key.RollNo + "<br />");
sb.Append("Student Name : " + item.Key.Name + "<br />");
foreach (var subjects in item.Value)
{
sb.Append("Subject No : " + subjects.SubjectNo + "<br />");
sb.Append("Subject Name : " + subjects.Type + "<br />");
}
}
Hope this helps.
Your requirements aren't clear, but it looks best to create a Subject class as well.
class Subject{
public int Id {get;set;}
public string Type {get;set;}
}
From there, you can change Dictionary<String, String> subjects to a simple List<Subject> type. And change addstudentinfo method to take a Subject as a parameter.
You can further improve it by ensuring that only one instance of a particular Subject ever exists by modifying the Subject class (For example, to use the Creator pattern).
You can create struct or class to contain student's info and than add it to Dictionary<string, StudInfo>, where string is student name as Key.
Class for storing student info:
public class StudInfo
{
public int RollNum;
public List<string> Activities = new List<string>();
public StudInfo(int num)
{
RollNum = num;
}
}
And its usage:
var dict = new Dictionary(string, StudInfo);
var info = new StudInfo(12);
dict.Add("Ellis", info);

Categories

Resources