How can I box the result of a LINQ select into multiple objects? With the following select clause:
select new {
Person = new Person((String)al.Element("firstName"), (String)al.Element("lastName")),
TimePeriod = new TimePeriod((String)al.Element("start"), (String)al.Element("end"))
};
In the example snippet above, Person and TimePeriod are totally unreleated object. Coming from a Scala background, I would have been happy if the result would be boxed into a tuple. Since I'm new to C#, can anyone help me with this?
If you want to put them into a Tuple you can do this
select Tuple.Create(new Person(...), new TimePeriod(...));
But it would be more advisable to create your own class
public class PersonAndTime
{
public PersonAndTime(Person person, TimePeriod timePeriod)
{
Person = person;
TimePeriod = timePeriod;
}
public Person Person{ get; private set; }
public TimePeriod TimePeriod {get; private set; }
}
And do this
select new PersonAndTime(new Person(...), new TimePeriod(...));
If you don't need to pass the results of the query into or out of a method then leaving it in the anonymous class should be fine.
Related
I'm currently looking into inheritance and polymorphism and I'm a bit confused about where you'd want to create a Person object of type Student?
assuming the following code:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
class Student : Person
{
public int YearOfStudy { get; set; }
public string Course { get; set; }
public string PredictedGrade { get; set; }
}
Now looking online, there are a few options here in terms of creating an object:
Person p = new Person();
Student s = new Student();
Person ps = new Student();
The first objects allows me to set name, age and gender, while the second allows me to set those 3, as well as yearsOfStudy, course and predictedGrade. But I'm unsure of what the third object allows me to do? I can still set all 6 parameters, however I can only use the attributes set in the Person class? Any explanation on the correct usage of the third object would be appreciated.
Thanks
Don't think of this as Person ps = new Student() yet.
The real benefit is being able to abstract common code for all types of Person. So your methods may take in a Person because that's all it needs and will work with any person type you create such as Janitor, Teacher, etc.
var myStudent = new Student()
VerifyAge(myStudent);
VerifyYearOfStudy(myStudent);
public bool VerifyAge(Person person)
{
return person.Age < 200;
}
public bool VerifyYearOfStudy(Student student)
{
return student.YearOfStudy <= DateTime.Now.Year;
}
To clear up some confusion the only time you ever really declare the base in a method is when you want to actually denote that this variable is only meant to be used as that specific type. Think of it as if you had declared your variable using an interface instead. Sure I am working with a Student instance, but I am only working with it as a Person instance or as IPerson.
Normally as a variable in a method you wouldn't do that because pretty much the defacto standard is to just use var for everything nowadays. Where you do make the choice to define Person is normally on properties, method return values, and method parameters. Local variable is not really important.
Because Student class is derived from Person class, any Student object is also a Person object. Thus a notation Person ps = new Student(); means we're declaring variable ps to be of type Person and instantiate it as Student. It could be used if you have a method that takes Person object as parameter, e.g.
public void Foo(Person p) { if(p.Age > 21) Console.WriteLine("OK to drink!"); }
However, if you have a method that operates on properties of derived class you must declare and instantiate the instance of it. So for
public void Foo(Student s) {if(s.YearOfStudy == 1) Console.WriteLine("Freshman"); }
you must use Student s = new Student();.
Let's say I have an ObservableCollection<Person>.
Now, every student can have some sort of opinion on every other person. What would be the best way to code something like this, so that it's accessible from both objects?
I thought about something like this for a relations:
enum RelationPoint { Neutral, Like, Dislike, Love, Hate }
List<RelationPoint> relation;
How can I define something like this for every person?
You could create an object, which stores the opinion in an object, like this:
public class Opinion
{
public Person Destination
{
get;
set;
}
public Person Target
{
get;
set;
}
public RelationPoint RelationType
{
get;
set;
}
}
If you store them like this in a list, every person can have an opinion abount another pserson.
To figure out, which person has which optinion, you can simply find this out using linq:
var goodRelation = listOfOption.Where(item => item.RelationType == RelationPoint.Like && item.Destination = <<Some Person>>);
Now you know, which person the Destination likes.
One solution would be to make an object called "Relation" which contains 2 persons.
So you would have following classes:
public class Person
{
public String Name;
....
}
and a class "Relation:
public class Relation
{
private Person p1;
private Person p2;
private String opinion;
}
Now you could make sth. like this:
Person p = new Person ("John");
Person p2 = new Person ("David");
Relation r1 = new Relation(p, p2, "Neutral");
Just one of many solutions.
Is it possible to assign list of objects to another list of objects that takes it as a constructor?
Eg.
public class PersonORM{
public PersonORM(Person p){ /* convert */ }
public int PersonId { get; set; }
/* Other properties here */
}
public class Person{
public int PersonId { get; set; }
/* Other properties here */
}
How do I convert Person to PersonORM using the constructor when they are in a list like this:
List<Person> people = getPeople();
List<PersonORM> peopleOrm = new List<Person>(people); // Is something like this possoble?
It is not possible to do that with the syntax you have as the constructor of List<T> does not support it.
If you can use linq (depending on which version of .Net you are targeting), you can do this:
List<PersonORM> personOrm = people.Select(p => new PersonORM(p)).ToList();
This uses the Select operator to perform the conversion from each item in the original list.
It can be done using LINQ:
List<PersonORM> peopleOrm = new List<Person>(people.Select(p => new PersonORM(p)));
Say I have an Employee class and one of its properties is of type Department. In my GUI, I want to create a new Employee and I instantiate it. I have a collection displayed through a ComboBox of Department objects, so that the end-user can select (assign) a Department for each Employee.
My question is, say when I instantiate this Employee class and I want to default the Department to some value, say "Finance" which is for the Department.Code property.
How can I do this?
I tried but doesn't seem to like when saving:
this.Employee = Employee.CreateEmployee("-1", DateTime.Now, "Active", ...);
this.Employee.Department= new Department { Code = "Finance" };
Any advice will be greatly appreciated.
Generally classes are built with constructors; ie
public class Department
{
string _code = "";
public Department() {}
public Department(string code) {
_code = code;
}
}
So that when your program creates a new department object, you can do:
Department finance = new Department("Finance");
this.Employee = Employee.CreateEmployee("-1", DateTime.Now, "Active", ...);
this.Employee.Department= finance;
Edit: You'd probably be better off using enumerators for this, such that you can declare an enumerator:
public enum Departments
{
Finance,
Technology,
Sales
}
public class Employee
{
Departments _employeeDepartment;
public Employee() {}
public Employee(Department EmployeeDepartment)
{
_employeeDepartment = EmployeeDepartment;
}
}
I am trying to get into LINQ to objects as I can see the power of it. Lucky enough I have a question that I think LINQ should be able to solve.
Here is the question (the details are an example);
public class SchoolClass
{
public int ID;
public string Name;
public string Teacher;
public string RoomName;
public string Student_Name;
public int Student_Age;
}
As you can see by the example, there is a one to many relationship between the ClassName, Teacher and Room and the Students, i.e. there are potentially many students in the one class.
If we have a List is it possible using LINQ to create a List but have only one instance ID, Name, Teacher, RoomName and an ArrayList of Student_Name and Age?
Producing this:
public class Students
{
public string Student_Name;
public int Student_Age;
}
public class SchoolClass
{
public int ID;
public string Name;
public string Teacher;
public string RoomName;
public ArrayList Students;
}
Essentially, using LINQ to clean the List to a more logical structure?
To give some background to this example. The second structure is used by a DataGrid to produce a Master-Child relationship. We store SchoolClass and StudentInformation in classes as shown above. It would be good use of LINQ to be able to convert our initial List into a structure which can be used by the DataGrid.
I changed the ArrayList to List<Students>, and:
List<SourceData> source = new List<SourceData>();
//...your data here ;-p
var classes = (from row in source
group row by new {
row.ID, row.Name,
row.Teacher, row.RoomName }
into grp
select new SchoolClass
{
ID = grp.Key.ID,
Name = grp.Key.Name,
Teacher = grp.Key.Teacher,
RoomName = grp.Key.RoomName,
Students = new List<Students>(
from row in grp
select new Students
{
Student_Age = row.Student_Age,
Student_Name = row.Student_Name
})
}).ToList();
If I'm understanding this correctly, I would've thought the best way to implement the SchoolClass class would be to create a Student class (probably a LINQ-to-SQL entity, if you're using it) and to have a generic list of type student, something similar to this:
public class SchoolClass
{
public int ID;
public string Name;
public string Teacher;
public string RoomName;
public List<Student> Students;
}
The list of students could then be populated using a linq query, although I'm not sure exactly how without more information.
Hope this is some help.