Class Person
{
string Name
int yesno
int Change
List<Cars> Personcars;
houses Personhouses
}
Person user1 = new Person()
Person user2 = new Person()
user1.Name = "userName"
user2.Name ="";
user2.cars[0] = new car("Mazda");
user1.cars[0] = new car("BMW");
i want to merge the objects so that user2 will take the name and the car from user1
user2 will have this values
user2.Name will be userName
user2.cars will hold the Mazda and the Bmw
thanks !
user2.Name = user1.Name;
user2.Personcars.AddRange(user1.Personcars);
You could add this as a method on the class itself:
public class Person
{
List<Cars> _personcars;
public string Name { get; set; }
// what the hell is a yesno int? If it's 1 or 0 then just use a bool
public int yesno { get; set; }
public int Change { get; set; }
public List<Cars> Personcars
{
get
{
return _personcars ?? (_personCars = new List<Cars>());
}
set { _personcars = value; }
}
public Houses Personhouses { get; set; }
public void Merge(Person person)
{
Name = person.Name;
Personcars.AddRange(person.Personcars);
}
}
Which will allow you to write something like this:
user2.Merge(user1);
Try this extension methods
public void Merge(this Person _person, Person source)
{
_person.Name = source.Name;
if(_person.Cars !=null)
{
_person.Cars.AddRang(source.Cars);
}
else
{
_person.Cars = source.Cars;
}
}
Related
Hi there I was wondering if its possible for me to create a method in my customer.cs to delete a customer depending on its ID. How I want this to work is that the user will select a customer from the list box which only shows the customers firstName and then hit delete which will delete the customer off the list box. But I want to somehow create a method in the customer.cs which will look at the ID then delete it if its the right one. Can this be done? Any help would be create thank you.
form.cs:
public partial class AddCustomer : Form
{
List<Customer> list = new List<Customer>();
Random rand = new Random();
public AddCustomer()
{
InitializeComponent();
}
// Adds Customer
private void buttonAddCustomer_Click(object sender, EventArgs e)
{
Customer customer = new Customer();
customer.customerId = rand.Next();
customer.firstName = textBoxfn.Text;
list.Add(customer);
listBoxCustomers.Items.Add(customer.firstName);
}
// Deletes Customer
private void buttonDeleteCustomer_Click(object sender, EventArgs e)
{
listBoxCustomers.Items.Remove(listBoxCustomers.SelectedItem);
}
}
}
Customer.cs:
public class Customer
{
public int customerId;
public string firstName;
public string lastName;
public string phoneNumber;
public string address;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public string PhoneNumber
{
get { return phoneNumber; }
set { phoneNumber = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
}
One idea is to load your customer list into a BindingList<Customer>
Now with this approach you work from the BindingList and the selected index of the ListBox.
I used a pre-defined customer class I had.
public class Customer
{
public int CustomerIdentifier { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public int CountryIdentifier { get; set; }
public override string ToString() => $"{FirstName} {LastName}";
}
Mocked data
public class MockedData
{
public static List<Customer> Customers() => new List<Customer>()
{
new Customer()
{
CustomerIdentifier = 1, FirstName = "Jim", LastName = "Adams",
Street = "120 Hanover Sq.", City = "London", PostalCode = "WA1 1DP",
CountryIdentifier = 19
},
new Customer()
{
CustomerIdentifier = 2, FirstName = "Mary", LastName = "Adams",
Street = "1 rue Alsace-Lorraine", City = "Toulouse", PostalCode = "31000",
CountryIdentifier = 8
},
new Customer()
{
CustomerIdentifier = 3, FirstName = "Karen", LastName = "White",
Street = "120 Hanover Sq.", City = "London", PostalCode = "WA1 1DP",
CountryIdentifier = 19
}
};
}
Form code
public partial class Form1 : Form
{
private readonly BindingList<Customer> _customersBindingList;
public Form1()
{
InitializeComponent();
_customersBindingList = new BindingList<Customer>(MockedData.Customers());
listBoxCustomers.DataSource = _customersBindingList;
}
private void RemoveCurrentButton_Click(object sender, EventArgs e)
{
if (listBoxCustomers.SelectedIndex > -1)
{
_customersBindingList.RemoveAt(listBoxCustomers.SelectedIndex);
}
RemoveCurrentButton.Enabled = listBoxCustomers.SelectedIndex > -1;
}
}
Here is the function to remove all customers with a certain id :
private void RemoveCustomer(int id)
{
list.RemoveAll(c => c.customerId == id);
}
I'm having issues trying to pass a list as an argument. I'm not sure what I'm doing wrong. In the following I have an AssociatedTexts list that I am adding to a Books list with the addBook function. The AssociatedTexts that are being selected aren't being saved and assigned to that specific list item in the Books list.
Book dictionary = new Book(ID, textBox1.Text, Product.AssociatedTexts);
Inventory.addBook(dictionary);
The addBook function looks like this:
public static void addBook(Book dictionary)
{
Books.Add(dictionary);
}
And here's the constructor for Book:
public Book(int bookID, string name, BindingList<Book> assocText)
{
BookID = bookID;
Name = name;
AssociatedTexts = assocText;
}
You requested the entire Book class so here it is:
public class Book
{
public static BindingList<Text> AssociatedTexts { get; set; }
public string Name { get; set; }
public int BookID { get; set; }
public int TextID { get; private set; }
public Book()
{
}
public Book(int bookID, string name)
{
BookID = productID;
Name = name;
}
public Book(int bookID, string name, BindingList<Text> assocText)
{
BookID = bookID;
Name = name;
AssociatedTexts = assocText;
}
public static void addAssociatedTexts(Text text)
{
AssociatedTexts.Add(text);
}
public static bool removeAssociatedText(int textID)
{
bool ret = false;
if (Book.AssociatedTexts.Count > textID)
{
Book.AssociatedTexts.RemoveAt(textID);
ret = true;
}
else
{
ret = false;
}
return ret;
}
public Part lookupAssociatedTexts(int searchPart)
{
for (int i = 0; i < AssociatedTexts.Count; i++)
{
if (AssociatedTexts[i].TextID == searchPart)
{
return AssociatedTexts[i];
}
}
return null;
}
What I am trying to accomplish is for each entry in the list of Books to have it's own list of AssociatedTexts. I am mapping these onto datagridviews and the user is able to add their own books with their own varying associatedtexts onto it but I am having trouble associating each associatedtexts list with each Book
As each book shall have its own list of associated texts, AssociatedTexts must not be static. Otherwise, all books will share the same list.
Also, I suggest to replace BindingList by List as Book is a typical model class and should not contain such UI-related members.
public class Book
{
public List<Text> AssociatedTexts { get; set; }
public string Name { get; set; }
public int BookID { get; set; }
public Book(int bookID, string name, IEnumerable<Text> assocText)
{
BookID = bookID;
Name = name;
AssociatedTexts = assocText.ToList();
}
public void addAssociatedText(Text text)
{
AssociatedTexts.Add(text);
}
public bool removeAssociatedText(int textID)
{
bool ret = false;
if (AssociatedTexts.Count > textID)
{
AssociatedTexts.RemoveAt(textID);
ret = true;
}
else
{
ret = false;
}
return ret;
}
public Part lookupAssociatedTexts(int searchPart)
{
for (int i = 0; i < AssociatedTexts.Count; i++)
{
if (AssociatedTexts[i].TextID == searchPart)
{
return AssociatedTexts[i];
}
}
return null;
}
}
I have following two classes
public class Family
{
public string ChildName { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public Family Child { get; set; }
}
I have an instance of Employee class as follows.
Employee employee = new Employee();
employee.Name = "Ram";
employee.Id = 77;
employee.Child = new Family() { ChildName = "Lava" };
I have a method which gets the property value based on the property name as follows:
public static object GetPropertyValue(object src, string propName)
{
string[] nameParts = propName.Split('.');
if (nameParts.Length == 1)
{
return src.GetType().GetRuntimeProperty(propName).GetValue(src, null);
}
foreach (String part in nameParts)
{
if (src == null) { return null; }
Type type = src.GetType();
PropertyInfo info = type.GetRuntimeProperty(part);
if (info == null)
{ return null; }
src = info.GetValue(src, null);
}
return src;
}
In the above method,when I try to get property value of nested class like
GetPropertyValue(employee, "employee.Child.ChildName")
or
GetPropertyValue(GetPropertyValue(employee, "Family"), "ChildName"
doesn't return any value because type.GetRuntimeProperty(part) is always null.
Is there any way to fix this problem?
You problem lies in this line:
foreach (String part in nameParts)
Because you are iterating over each part of nameParts, you are also iterating over "employee", which of course is not a valid property.
Try either this:
foreach (String part in nameParts.Skip(1))
Or calling the method like this:
GetPropertyValue(employee, "Child.ChildName")
(Notice no "employee.", because you already pass in an employee)
The problem in this case is that when you split the string employee.Child.ChildName, the "employee" is the first part. However, employee is not a property of the source i.e. Employee Class.
Try this:
public class Program
{
public static void Main()
{
Employee employee = new Employee();
employee.Name = "Ram";
employee.Id = 77;
employee.Child = new Family() { ChildName = "Lava" };
GetPropertyValue(employee, "employee.Child.ChildName");
}
public class Family
{
public string ChildName { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public Family Child { get; set; }
}
public static object GetPropertyValue(object src, string propName)
{
string[] nameParts = propName.Split('.');
if (nameParts.Length == 1)
{
return src.GetType().GetRuntimeProperty(propName).GetValue(src, null);
}
nameParts = nameParts.Skip(1).ToArray();
foreach (String part in nameParts)
{
if (src == null) { return null; }
Type type = src.GetType();
PropertyInfo info = type.GetRuntimeProperty(part);
if (info == null)
{ return null; }
src = info.GetValue(src, null);
}
return src;
}
Here, i have skipped the first part of the string i.e. "employee". However, you can solve the problem by passing Child.ChildName
This question is around 2 years old, but I found a another working solution for you question, which is easy to understand. If you initialize the object in calling calss constructor you can use dot(.) notation to assign or read property. Example -
public class Family{
public string ChildName { get; set; }
}
public class Employee{
public int Id { get; set; }
public string Name { get; set; }
public Family Child { get; set; }
public Employee(){
Child = new Family();
}
}
Employee emp = new Employee();
emp.Family.ChildName = "Nested calss attribute value";
Hey guys I want to achieve something like this
class Program
{
static void Main(string[] args)
{
Responsible responsible = new Responsible()
{
//I want here to populate with PopulatePerson the base members
Phone = "93827382",
Company = "Google"
};
}
public Person PopulatePerson(string pName, string pLastName)
{
Person person = new Person();
person.Name = pName;
person.LastName = pLastName;
return person;
}
}
public class Person
{
public string Name { get; set; }
public string LastName { get; set; }
}
public class Responsible : Person
{
public string Phone { get; set; }
public string Company { get; set; }
}
The case is more complex with database queries and stuff but basically this is what I need
I could use a member called Person in Responsible and do Person = PopulatePerson("Dan", "Johns") but since I'm inheriting I find it kinda redundant
What about something like this. I created a generic (static) factory method for Person that is reusable across all types that inherit from Person.
class Program
{
static void Main(string[] args)
{
//Responsible responsible = new Responsible()
//{
// //I want here to populate with PopulatePerson the base members
// Phone = "93827382",
// Company = "Google"
//};
var responsible = Responsible.Populate("Glenn", "Fake", "93827382", "Google");
//responsible
}
// NO LONGER NEEDED
// ============================
//public Person PopulatePerson(string pName, string pLastName)
//{
// Person person = new Person();
// person.Name = pName;
// person.LastName = pLastName;
// return person;
//}
}
public class Person
{
public string Name { get; set; }
public string LastName { get; set; }
public static TPerson Populate<TPerson>(string name, string lastname) where TPerson : Person, new()
{
TPerson person = new TPerson();
person.Name = name;
person.LastName = lastname;
return person;
}
}
public class Responsible : Person
{
public static Responsible Populate(string name, string lastname, string phone, string company)
{
var p = Responsible.Populate<Responsible>(name, lastname);
p.Phone = phone;
p.Company = company;
return p;
}
public string Phone { get; set; }
public string Company { get; set; }
}
Not sure if it makes sense your real scenario but you could change PopulatePerson to accept a Person object as an input parameter instead of internally creating a new one. Then you could pass your new Responsible object to it and afterwards set Phone and Company.
Edit: Like this
class Program
{
static void Main(string[] args)
{
Responsible responsible = new Responsible();
PopulatePerson(responsible, "first", "last");
responsible.Phone = "93827382";
responsible.Company = "Google";
}
public static void PopulatePerson(Person person, string pName, string pLastName)
{
person.Name = pName;
person.LastName = pLastName;
}
}
public class Person
{
public string Name { get; set; }
public string LastName { get; set; }
}
public class Responsible : Person
{
public string Phone { get; set; }
public string Company { get; set; }
}
I have this:
public class Blah
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh
{
public int id { get; set; }
public string dohh { get; set; }
public string mahh { get; set; }
}
public List<???prpClass???> Whatever(string prpClass)
where string prpClass can be "Blah" or "Doh".
I would like the List type to be class Blah or Doh based on what the string prpClass holds.
How can I achieve this?
EDIT:
public List<prpClass??> Whatever(string prpClass)
{
using (var ctx = new ApplicationDbContext())
{
if (prpClass == "Blah")
{
string queryBlah = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Blah>(queryBlah).ToList();
return result;
}
if (prpClass == "Doh")
{
string queryDoh = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Doh>(queryDoh).ToList();
return result;
}
return null
}
}
you have to have a common supertype:
public interface IHaveAnId
{
int id { get;set; }
}
public class Blah : IHaveAnId
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh : IHaveAnId
{
public int id {get;set;}
public string dohh { get; set; }
public string mahh { get; set; }
}
then you can do:
public List<IHaveAnId> TheList = new List<IHaveAnId>();
and in some method:
TheList.Add(new Blah{id=1,blahh = "someValue"});
TheList.Add(new Doh{id =2, dohh = "someValue", mahh = "someotherValue"});
to iterate through the list:
foreach(IHaveAnId item in TheList)
{
Console.WriteLine("TheList contains an item with id {0}", item.id);
//item.id is allowed since you access the property of the class over the interface
}
or to iterate through all Blahs:
foreach(Blah item in TheList.OfType<Blah>())
{
Console.WriteLine("TheList contains a Blah with id {0} and blahh ='{1}'", item.id, item.blahh);
}
Edit:
the 2 methods and a int field holding the autovalue:
private int autoValue = 0;
public void AddBlah(string blahh)
{
TheList.Add(new Blah{id = autovalue++, blahh = blahh});
}
public void AddDoh(string dohh, string mahh)
{
TheList.Add(new Doh{id = autovalue++, dohh = dohh, mahh = mahh});
}
Another Edit
public List<object> Whatever(string prpClass)
{
using (var ctx = new ApplicationDbContext())
{
if (prpClass == "Blah")
{
string queryBlah = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Blah>(queryBlah).ToList();
return result.Cast<object>().ToList();
}
if (prpClass == "Doh")
{
string queryDoh = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Doh>(queryDoh).ToList();
return result.Cast<object>.ToList();
}
return null;
}
}
in the view you then have to decide what type it is. In asp.net MVC you can use a display template and use reflection to get a good design. But then i still don't know what technology you are using.
Yet another Edit
TestClass:
public class SomeClass
{
public string Property { get; set; }
}
Repository:
public static class Repository
{
public static List<object> Whatever(string prpClass)
{
switch (prpClass)
{
case "SomeClass":
return new List<SomeClass>()
{
new SomeClass{Property = "somestring"},
new SomeClass{Property = "someOtherString"}
}.Cast<object>().ToList();
default:
return null;
}
}
}
And a controller action in mvc:
public JsonResult Test(string className)
{
return Json(Repository.Whatever("SomeClass"),JsonRequestBehavior.AllowGet);
}
then i called it with: http://localhost:56619/Home/Test?className=SomeClass
And got the result:
[{"Property":"somestring"},{"Property":"someOtherString"}]
Is this what you are trying to do?
public class Blah
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh
{
public int id { get; set; }
public string dohh { get; set; }
public string mahh { get; set; }
}
class Program
{
public static List<T> Whatever<T>(int count) where T: new()
{
return Enumerable.Range(0, count).Select((i) => new T()).ToList();
}
static void Main(string[] args)
{
var list=Whatever<Doh>(100);
// list containts 100 of "Doh"
}
}