Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I need some help.
I'm trying to store information inside of lists.
For example, the user types in number, age, address and hair color...
And I want to make lists inside of lists to store the information, like this:
[0] Number
----[0] Age
----------[0] Address
----------[1] Adrress
--------------[0] Hair Color
If there is a better way to do this please help me!
With lists inside of list I will be very confused, but if it is the better solution, I've no problem.
Storing logically-grouped data as arrays of primitive values isn't really the way to go with this. Instead, replace the array with an object and just store the list of objects. In your example, the object could be as simple as:
class Person
{
public int Number { get; set; } // it's not clear what this value means
public int Age { get; set; }
public string Address { get; set; }
public string HairColor { get; set; }
}
You can add more properties, logic, validation, strongly-typed enumerations (for things like HairColor), etc. to this object. Maintaining a collection of this is easy:
var people = new List<Person>();
One of the key benefits you'd immediately notice with this approach is that the structure of the Person can change without having to change any of the collections which store Persons. You can add/alter/remove properties and it's still just a List<Person>. You'd only have to change code which uses the components that you're changing.
Another key benefit is that you can encapsulate all of the logic which defines a Person within this class, so other code doesn't need to worry about it. So instead of having to re-write the same validation logic for example (always making sure Age is a valid positive number, things like that), you can just write it on the object and it's applied everywhere. As Eric Raymond once said, "Smart data structures and dumb code work a lot better than the other way around."
You need a class structure take a look at this example:
public enum AddressType{
Work,
Home,
Other
}
class Address{
public AddressType AddressType{get;set;}
public AddressLine1 {get;set;}
public AddressLine2 {get;set;}
public string City{get;set;}
public string State{get;set;}
}
class User
{
public int Age{get;set;}
public string FirstName{get;set;}
public string LastName{get;set;}
public string HairColor{get;set;}
public List<Address> AddressList{get;set;}
public User(){
AddressList = new List<Address>();
}
}
class UserList:List<User>{
}
Then you can make use of this code like this:
var users = new UserList();
var usr = new User{FirstName = "Steve", LastName="Ruben", Age = 32, HairColor = "Brown"};
usr.AddressList.Add(new AddressList{AddressLine1 = "Address ln 1", AddressLine2 = "Address ln 2", City = "Some Place", State = "WI", AddressType = AddressType.Home});
users.Add(usr);
Related
I have an Employee Class with different values, that I call from my Main Form, and I want to add a list element to my class, but it doesn't work as I want it to work.
My Employee Class looks like this:
public class Employee
{
public Employee(int id, string name, string mobil, string email,
List<string> listAttributes)
{
Id = id;
Name = name;
Mobil = mobil;
Email = email;
ListAttributes = listAttributes;
}
public int Id { set; get; }
public string Name { set; get; }
public string Mobil { set; get; }
public string Email { set; get; }
public List<string> ListAttributes { set; get; }
}
On my main form I have a list of employee like this:
public List<Employee> WorkerDatas = new List<Employee>();
And a list like this for the attributes:
public List<string> Attributes = new List<string>();
And I add new emloyee datas into this list with an "Add Employee Button". The button's On_Click event is like this:
private void btnAdd_Click(object sender, EventArgs e)
{
WorkerDatas.Add(new Employee(EmployeeIndex, txbName.Text, txbMobil.Text, txbEmail.Text, Attributes));
}
Everything works fine as I want (the Id, name, mobile, email), but the list (Attributes) doesn't work properly.
If I add 1 employee, it looks like its working, but when i add a second one, my first employee has the same attributes as my second. (I choose attributes from a CheckedListBox, there are 7 attributes that my employees may or may not have.)
I hope that I was clear, I could not find similar problem with solutions, so I had to ask. Thank you for any help! :)
my psychic debugging powers are telling me that you're passing the same list into each Employee Constructor, List<T> is a reference type, which means that the variable that holds is only holds a pointer to the real list.
A consequence of that is that every Employee, has the exact same list, and when you change, it, you change it for all employees.
You should construct a brand new list of Attributes to pass into each Employee.
since, string is immutable and behaves mostly the same as a value type does, you only have to worry about the list itself. adding a ToList() should do the trick. ToList() always returns a new list.
WorkerDatas.Add(new Employee(EmployeeIndex, txbName.Text, txbMobil.Text, txbEmail.Text, Attributes.ToList()));
Note, if Attributes was a list of some other non-immutable reference type, you'd have to make copies of the elements too.
I was asked a question yesterday that is throwing me for a loop. I was asked to implement the interface IPeopleFinder:
public interface IPeopleFinder
{
IEnumerable<Person> GetByAge(List<Person> people, int age);
IEnumerable<Person> Find<TType>(Func<IEnumerable<TType>, bool> filter);
}
on this class:
public class People
{
public List<Student> Students { get; }
public List<Teacher> Teachers { get; }
}
The first function is simple, but the second function I do not understand what it is trying to do:
IEnumerable<Person> Find<TType>(Func<IEnumerable<TType>, bool> filter);
The IEnumerable<TType> in the Func is what I do not understand. If the signuture was:
IEnumerable<Person> Find<TType>(Func<TType, bool> filter);
it would be a simple matter of passing the filter to the IEnumerable<T>.Where() function.
Could someone please explain how filter function accepting an IEnumerable<T> and returning a bool would work? I'm starting to think it is a typo and should be Func<TType, bool>.
Clarification on restraints:
Classes are defined thus:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ushort Age { get; set; }
public Sex Sex { get; set; }
}
public class Student : Person
{
public Major Major { get; set; }
}
public class Teacher : Person
{
public Department Department { get; set; }
}
TType is restricted to be of type Person.
The way the question is written, once the Find method is implemented, it is to be used to find all Students majoring in a certain subject, and all Teachers belonging to a certain department.
Obviously the method should work for enumerations of enumerations such as
var l = new List<List<Student>>();
Now you can call myPeopleFinder.Find(x => x.Any()) which would return an enumeration of students.
A better example would be to filter those sub-lists from your enumeration that have a specific size:
myPeopleFinder.Find(x => x.Count() > 30)
EDIT: For a practical use-case imagine a school as a list of classes where every class itself has a list of Student and Teacher. Now you want to get all those classes that have more then a given amount (30 in my example) of Person (assuming that either Student and Teacher inherit from Person). Finally this method may flatten the resulting sub-lists into one single enumeration of type Person to get all the students and teachers within the overfull classes.
EDIT2: As you´re concerning to the properties of the persons instead of the list you should of course - as you´ve already assumed - use a Func<TType> with TType : Person. Seems like a type to me too.
I agree with your analysis and I wonder what kind of specification you got and from where.
The person who defined the IPeopleFinder interface should not only write code but also document it, at least in source code, better yet: describe the reason for the interface in a requirements document, define the context in a software architecture document and describe the detailed use in a design document.
As long as you only have the interface and no further description, just throw a NotImplementedException since it has not been defined that you should do something else.
Is there in C# any hydrating technique allowing to transfer values from one struct/object to another struct/object if they have similar fields or based on certain strategy. I came from Zend Framework 2 world, and it provides the feature "Hydrator" which allows do exactly what I said above. So, I am wondering whether Asp.Net or C# provides something similar.
To make it clear, I want something like this:
struct UserInfo {
public string FirstName { get; set; };
public string LastName { get; set; };
public int Age { get; set; };
}
class UserUpdateModel {
public string FirstName { get; set; };
public string LastName { get; set; };
public int Age { get; set; };
}
...
//supposed UserUpdateModel model I is gotten from the action param
UserInfo info = new UserInfo();
Hydrator hydrator = new Hydrator(Hydrator.Properties);
hydrator.hydrate(info, model);
Now, "info" should be populated with values from "model"
Any help is appreciated.
Yes. AutoMapper. It is designed specifically for this. I personally prefer writing ViewModel constructor that takes an entity and copies the properties. I like the control and familiarity of good old C# code even if it takes a bit more effort.
Automapper should do the trick. You can use it as a nuget package.
Once you have your types and a reference to AutoMapper, you can create a map for the two types.
Mapper.CreateMap<UserUpdateModel, UserInfo>();
The type on the left is the source type, and the type on the right is the destination type. To perform a mapping, use the Map method.
UserInfo info = Mapper.Map<UserInfo>(userUpdateModel);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I've got a bit of a problem trying to add an object to a list. I am working in c#.
Object with List of Objects:
public class Person
{
public string Title { get; set; }
public List<Names> FullNames { get; set; }
}
Names Object
public class Names
{
string First { get; set; }
string Middle { get; set; }
string Last { get; set; }
public Names(string First, string Middle, string Last)
{
this.First = First;
this.Middle = Middle;
this.Last = Last;
}
}
The Problem Area:
In the MainWindow, I create an Observable Collection of type Person. How do you correctly implement adding the FullNames list? I haven't been able to make it work at all.
public partial class MainWindow : Window
{
public ObservableCollection<Person> people { get; set; }
public MainWindow()
{
InitializeComponent();
people.Add(new Person() { Title = "President", FullNames = new Names(First = "George", Middle = "K", Last = "Will")}); //problem area
}
}
Alright, a few things.
You've got a NullReferenceException waiting to happen. people is initialized as null, and you're adding directly to it without giving it an instance.
You have a collection containing Person objects, and you're adding a TodoItem to it. One of those is wrong.
Your real question, you need to use the List initializer on the FullNames property, because it looks like you're trying to set a List<T> = T, which doesn't make any sense.
You are calling a constructor of Names with =, which is bad syntax. You want to leave out the parameter names. As #RohitVats points out, you could also use : to specify, but here you really don't want to. A constructor is really just a method call, so the same syntax rules applies to them as any other function (for the most part).
To address these concerns, your code would look something like this:
public MainWindow()
{
InitializeComponent();
people = new ObservableCollection<Person>();
people.Add(new Person()
{
Title = "President",
FullNames = new List<Names>()
{
new Names("George", "K", "Will")
}
});
}
For the sake of making sure you understand what's going on here, this would be the same as writing:
public MainWindow()
{
InitializeComponent();
people = new ObservableCollection<Person>();
Person toAdd = new Person();
toAdd.Title = "President";
toAdd.FullNames = new List<Names>();
toAdd.FullNames.Add(new Names("George", "K", "Will"));
people.Add(toAdd);
}
This one isn't a bug, but you should really consider adjusting your Names type name to be something singular, even just FullName, because it's hard to read as it stands. I get where you're coming from, since there are in fact multiple names (first, middle, and last), but it's still confusing.
Initialize people list first.
You can only add Person object in your collection.
Names should be initialized to list.
Constructor call with arguments is not correct.
Instead of First = "George", it should be First : "George" or simply omit the arguments name altogether if passing in same order as in definition.
This should work:
people.Add(new Person() { Title = "President",
FullNames = new List<Names>()
{ new Names("George", "K", "Will") } });
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have to create class like DataBase that will contain menu, adding users, editing them, deleting etc.
Users are from class User.
It looks like:
class base
{
protected int mAccounts=0;
protected const int mMaxAccs=10;
osoba[] list = new osoba[mMaxAccs];
public void menu(){...}
public void add()
{
user user1("Jurand","ze Spychowa",15231512,"1410-10-26","hue#x.com");
mAccounts++;
}
... useless code there
}
then there is User class
class user
{
private string mName;
private string mSurname;
private int mPesel;
private DateTime mBDate;
private string mEmail;
osoba(string mName2, string mSurname2, string mPesel2, string mBDate2, string mEmail2)
{
mName = mName2;
mSurname = mSurname2;
mPesel = Convert.ToInt32(mPesel2);
mBDate = Convert.ToDateTime(mBDate2);
mEmail = mEmail2;
}
The problem is adding new accounts. I totally don't know how to make it working
So the users will be stored in base class and you will have access to edit and add them etc.
Anyone know how to make it working (Creating objects properly)?
I suggest adding properties to User class:
class User
{
public string mName { get; private set; }
public string mSurname { get; private set; }
public int mPesel { get; private set; }
public DateTime mBDate { get; private set; }
public string mEmail { get; private set; }
//constructor for User class
public User(string mName2, string mSurname2, string mPesel2, string mBDate2, string mEmail2)
{
mName = mName2;
mSurname = mSurname2;
mPesel = Convert.ToInt32(mPesel2);
mBDate = Convert.ToDateTime(mBDate2);
mEmail = mEmail2;
}
}
and modify your add method (also changed object where you store data from array to List):
class MyDB
{
List<User> list = new List<User>();
public void add()
{
//use constructor to create new object
User person = new User("Jurand", "ze Spychowa","15231512","1410-10-26","hue#dupa.com");
//add object to list
list.Add(person);
}
}
Its not good idea to mix different languages in code so try avoiding naming objects/methods like "osoba".
You will probably benefit from reading following articles (in Polish):
C# Constructors
C# Properties
I belive that only thing that is missing in your add() method is:
osoba[mAccounts] = user1;
before mAccounts++ line.
Make fields public only if your User class is going to be stupid data object which only store data and contain no methods (maybe except formatting, converting etc.).