Want to create multiple objects of a class at runtime - c#

I am a complete fresher I have been told to create a class for Candidate ..
after creating the database for the module. What I have created is
public class Class1
{
public class JobHistory
{
public string CompName, Tech, Profile;
public string StartDate;
public string EndtDate;
public int CurrentAnnualSalary;
public void AddNew(string CompName, string Tech, string Profile,
string StartDate, string EndtDate,
int CurrentAnnualSalary)
{
this.CompName = CompName;
this.Tech = Tech;
this.Profile = Profile;
this.StartDate = StartDate;
this.EndtDate = EndtDate;
this.CurrentAnnualSalary = CurrentAnnualSalary;
}
}
public class PersonalInformation
{
public string FirstName, LastName, DateOfBirth, PhoneNo1, PhoneNo2;
public string EmailId;
public int TotalExperienceInMonths;
public void AddNew(string FirstName, string LastName, string DateOfBirth,
string PhoneNo1, string PhoneNo2,
int TotalExperienceInMonths, string EmailId)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.DateOfBirth = DateOfBirth;
this.PhoneNo1 = PhoneNo1;
this.PhoneNo2 = PhoneNo2;
this.EmailId = EmailId;
this.TotalExperienceInMonths = TotalExperienceInMonths;
}
}
public class Skills
{
int SkillId;
string Skill;
}
public class Candidate
{
int CandidateId;
JobHistory jh1 = new JobHistory();
PersonalInformation pi = new PersonalInformation();
public void AddNew(int CandidateId,JobHistory jh2,PersonalInformation pi2)
{
this.CandidateId = CandidateId;
this.jh1.AddNew(jh2.CompName, jh2.Tech, jh2.Profile,
jh2.StartDate, jh2.EndtDate,
jh2.CurrentAnnualSalary);
this.pi.AddNew(pi2.FirstName, pi2.LastName, pi2.DateOfBirth,
pi2.PhoneNo1, pi2.PhoneNo2,
pi2.TotalExperienceInMonths, pi2.EmailId);
}
public void UpdateExisting();
public void Delete();
}
}
here I wanted to another class of Skills.
But from the frond end the candidate will have multiple skills and he will update them. So for that I wanted the objects of class skills to be created at the runtime so should I be using the List<>? How to go ahead? Am I correct till now?

As #Jon skeet mentioned you need to use the Constructor and you need to remove the class1 nested class rarely required.
Start with writing constructor for your classes in place of AddNew method like below
public class JobHistory
{
public string CompName, Tech, Profile;
public string StartDate;
public string EndtDate;
public int CurrentAnnualSalary;
public JobHistory(string CompName, string Tech, string Profile,
string StartDate, string EndtDate,
int CurrentAnnualSalary)
{
this.CompName = CompName;
this.Tech = Tech;
this.Profile = Profile;
this.StartDate = StartDate;
this.EndtDate = EndtDate;
this.CurrentAnnualSalary = CurrentAnnualSalary;
}
//If required then you can also need write out the empty constructor
public JobHistory(){}
}
You can also change your class1 into the namespace so your classes can stay in same namespace. More info on namespace
namespace StudeProfileProject
And one more thing, If you are declaring the properties as public then use the getters and setters at the time of declaration so your final class will be look like,
public class JobHistory
{
public string CompName{get;set}
public string Tech {get;set;}
public string Profile{get;set;}
//More properties ....
public JobHistory()
{}
public JobHistory(string CompName, string Tech, string Profile,
string StartDate, string EndtDate,
int CurrentAnnualSalary)
{
this.CompName = CompName;
this.Tech = Tech;
this.Profile = Profile;
this.StartDate = StartDate;
this.EndtDate = EndtDate;
this.CurrentAnnualSalary = CurrentAnnualSalary;
}
}
If you want multiple skills for each Candidate then List will be good option and you can declare it in the your Candidate class
public class Candidate
{
int CandidateId;
JobHistory jh1 = new JobHistory();
PersonalInformation pi = new PersonalInformation();
List<Skill> CandidateSkills = new List<Skills>();
public Candidate(int CandidateId,JobHistory jh2,PersonalInformation pi2)
{
this.CandidateId = CandidateId;
this.jh1= new JobHistory (jh2.CompName, jh2.Tech, jh2.Profile,
jh2.StartDate, jh2.EndtDate,
jh2.CurrentAnnualSalary);
this.pi = new PersonalInformation (pi2.FirstName, pi2.LastName, pi2.DateOfBirth,
pi2.PhoneNo1, pi2.PhoneNo2,
pi2.TotalExperienceInMonths, pi2.EmailId);
}
public void UpdateExisting();
public void Delete();
}
And you will be able to use all the Collection methods for your need. Here is more info on it.

First, you could replace the AddNew-Methods with Constructors.
For your Candidate class it could look like this:
public Candidate(int CandidateId,JobHistory jh2,PersonalInformation pi2)
Using a List<Skill> is a good idea. You can then use the Add-Method to add a skill.

Related

Winforms combobox displaying class names instead of actual object name

I have this class that contains a static list
public class TypeList
{
public string Name;
public string NameTag;
public TypeList(string Name, string NameTag)
{
this.Name = Name;
this.NameTag = NameTag;
}
public static List<TypeList> DataType = new List<TypeList>() {
new TypeList("DataType","-1"),
new TypeList("OpOne","1"),
new TypeList("OpTwo","2"),
};
}
I then put the static list called DataType into a combobox:
public void RefreshList()
{
List<TypeList> data = new List<TypeList>();
data = TypeList.DataType;
typeCB.DataSource = data;
typeCB.DisplayMember = "Name";
typeCB.ValueMember = "NameTag";
typeCB.SelectedValue = -1;
typeCB.SelectedText = "Select DataType";
}
However, when I run it, all I get are the classnames in my combobox. Is something wrong with my code? I tried to do
data.Select(x=>x.Name).ToList()
But that just gives me the name portion.
I might be wrong, but based on the Documentation and Example it might be that this Feature only works with public property getters, not public fields:
Gets or sets the property to display for this ListControl.
public class USState
{
private string myShortName;
private string myLongName;
public USState(string strLongName, string strShortName)
{
this.myShortName = strShortName;
this.myLongName = strLongName;
}
public string ShortName
{
get
{
return myShortName;
}
}
public string LongName
{
get
{
return myLongName;
}
}
}
Of course I would also advise against making the list a part of the Type class. A simple Programm scope static would be better. If that is the case and as autoproties have have become a thing by now, this should be enough of a fix:
public class Type
{
public string Name { private set; get } ;
public string NameTag {private set; get };
public TypeList(string Name, string NameTag)
{
this.Name = Name;
this.NameTag = NameTag;
}
}
//use in the class of main, the form or some similar central point
static List<Type> TypeList = new List<Type>();

JavaScriptSerializer does not serialize a second level

I am trying to use JavaScriptSerializer and I have got good results when I want to serialize a list of objects of a class like
public class employee
{
public string id; //unique id of the employee
public string displayName;
public int displayFlag;
public employee(string i, string dN, int dF)
{
id = i;
displayName = dN;
displayFlag = dF;
}
}
public class data2
{
public List<employee> detail;
}
When I do the following
var json = new JavaScriptSerializer();
string jsonData = json.Serialize(data2);
(and data2 is an object of class data2)
However when I try to do the same for something a little more complicated such as
public class Ccanister
{
string identifier;
public Ccanister(string c)
{
identifier = c;
}
}
public class medicine
{
public string id; //unique id
public string displayName;
//and here an array of canisters
public List<Ccanister> canister;
}
public class dataMedicine
{
public List<medicine> detail; //Change this
}
and I do this
string jsonMedi = json.Serialize(dataM);
I got wrong results.
dataM has correct results (I debugged it) but when jsonMedi gets its results, the canister list 'canister' is always empty. (It was not empty in dataM)
I wonder what I am doing wrong here

How to define baseclass or interface for constants?

In my application, I need to define a same set of Constant values for multiple classes and I want to use one baseclass/interface of all them as type param to my generic class.
//I know following code will not work, just trying to demonstrate the problem
public interface IConstantsDefined
{
static const string DbName;
static const string TableName;
static const string ColumnName;
}
public static class Product : IConstantsDefined
{
public static const string DbName = "ProductDB";
public static const string TableName = "Products";
public static const string ColumnName = "ProductId";
}
public static class Sales: IConstantsDefined
{
public static const string DbName = "SalesDb";
public static const string TableName = "Sales";
public static const string ColumnName = "SaleId";
}
public class DbConnection<TConsts> where TConsts : IConstantsDefined
{
// use TConsts.DbName, TConsts.TableName here
}
I understand that what I wrote above will throw many errors in C#. I know that static class can not inherit from interface. Question I have is, what is the best design/approach to build such a system, keeping performance and memory in mind?
Constants are defined and initialized once.
public interface IConstantsDefined
{
static const string Foo = "Foo";
static const string Bar = "Bar";
}
What you want are abstract get-only fields:
public interface IConstantsDefined
{
string DbName { get };
string TableName { get };
string ColumnName { get };
}
public class Product : IConstantsDefined
{
public string DbName { get { return "ProductDB" } };
public string TableName { get { return "Products" } };
public string ColumnName { get { return "ProductId" } };
}
public class Sales: IConstantsDefined
{
public string DbName { get { return "ProductDB" } };
public string TableName { get { return "Sales" } };
public string ColumnName { get { return "SaleId" } };
}
Since you don't need/want multiple instances of the Product and Sales types you might want to consider dropping the types altogether as this is pretty much the definition of a class:
public class ConstantsDefined
{
public string DbName { get; private set; };
public string TableName { get; private set; };
public string ColumnName { get; private set; };
public static readonly ConstantsDefined Product = new ConstantsDefined()
{
DbName = "ProductDB",
TableName = "Products",
ColumnName = "ProductId",
};
}
You can try as in the comment from #nabuchodonossor. Or, you can create Metadata classes, ProductMetadata and SalesMetadata which implement interface IMetadata. Then when needed, you could use a factory to get metadata instance by passing in the actual Model information(typeof(Sales) for example).
The closest one to achieve wanted is this, using base abstract class:
abstract class Base
{
public abstract string DbName { get; }
}
class Product : Base
{
public override string DbName => "ProductDB";
}
class Sales : Base
{
public override string DbName => "SalesDB";
}
class DbConnection<T> where T : Base
{
public string Test(T instance) => instance.DbName;
}
This indeed require instance, which can be hold by DbConnection, resolved by service provider, etc.
All my Product or Sales class would have is various constants, so I do not want to create instance of these
This requirement basically change everything. It seems you understand constant in given context as "a value which can't be changed". Which is immutable type. Then you do not need generics to construct type with constants, simply pass parameters (as you would do with any immutable type):
class DbConnection
{
public string DbName { get; }
public DbConnection(string dbName)
{
DbName = dbName;
}
}
Usage: instead of mysterious new DbConnection<Product>() you simply do new DbConnection("ProductDB"). If you have multiple parameters, then consider to wrap those and pass instance to constructor. And this is where you end up with abstract class and non-static inheritance as in my first snippet: new DbConnection(new Product()) (while DbConnection will require Base type to pass).

C# Base class constructor arguments

I learning C#. I want to see what is the best way to implement inheritance. I have a Employee base class and a PartTime derived class. Employee class only receives First and Last name and has a method to print full name.
I want to know what is the proper way to pass First and last name so that when I just call PartTime class I should be also able to print full name from the calling program. At the moment it is showing blank as full name:
class Program
{
static void Main(string[] args)
{
Employee emp = new Employee("John", "Doe");
// emp.PrintFullName();
PartTime pt = new PartTime();
float pay=pt.CalcPay(10, 8);
pt.PrintFullName();
Console.WriteLine("Pay {0}", pay);
Console.ReadKey();
}
}
public class Employee
{
string _firstName;
string _last_name;
public Employee(string FName, string LName)
{
_firstName = FName;
_last_name = LName;
}
public Employee() { }
public void PrintFullName()
{
Console.WriteLine("Full Name {0} {1} ", _firstName, _last_name);
}
}
public class PartTime : Employee
{
public float CalcPay(int hours, int rate)
{
return hours * rate;
}
}
You can call the base class constructor from you derived class like this:
public class PartTime : Employee
{
public PartTime(string FName, string Lname)
: base(FName, LName)
{ }
}
and then create it,
PartTime pt = new PartTime("Part", "Time");
Try this:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Employee(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
//method implementations removed for clarity
}
public class PartTime:Employee
{
public PartTime(string firstName, string lastName)
: base(firstName, lastName)
{
}
}
Note that your base constructor will run before any code in your derived constructor, should you need further initialization logic in the PartTime class.
You want to add a constructor to PartTime that will pass along the first and last name to the base constructor
public PartTime(string fName, string lName) : base(fName, lName) {
}
Or you could make first and last name public properties on Employee which would be inherited by PartTime. Then you can initialize them when creating instances of either without having to maintain the PartTime constructor.
class Program
{
static void Main(string[] args)
{
Employee emp = new Employee { FirstName = "John", LastName = "Doe" };
emp.PrintFullName();
PartTime pt = new PartTime { FirstName = "Jane", LastName = "Doe" };
float pay=pt.CalcPay(10, 8);
pt.PrintFullName();
Console.WriteLine("Pay {0}", pay);
Console.ReadKey();
}
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public void PrintFullName()
{
Console.WriteLine("Full Name {0} {1} ", FirstName, LastName);
}
}
public class PartTime : Employee
{
public float CalcPay(int hours, int rate)
{
return hours * rate;
}
}

Static implicit operator

I recently found this code:
public static implicit operator XElement(XmlBase xmlBase)
{
return xmlBase.Xml;
}
What does static implicit operator mean?
This is a conversion operator. It means that you can write this code:
XmlBase myBase = new XmlBase();
XElement myElement = myBase;
And the compiler won't complain! At runtime, the conversion operator will be executed - passing myBase in as the argument, and returning a valid XElement as the result.
It's a way for you as a developer to tell the compiler:
"even though these look like two totally unrelated types, there is actually a way to convert from one to the other; just let me handle the logic for how to do it."
Such an implicit operator means you can convert XmlBase to XElement implicitly.
XmlBase xmlBase = WhatEverGetTheXmlBase();
XElement xelement = xmlBase;
//no explicit convert here like: XElement xelement = (XElement)xmlBase;
Another interesting usage is (which Unity did to check if an object (and therefore an instance of MonoBehavior) is null):
public static implicit operator bool (CustomClass c)
{
return c != null;
}
Note that the code has to be inside the class (CustomClass in this case). That way you can do something like this:
void Method ()
{
CustomClass c1 = null;
CustomClass c2 = new CustomClass ();
bool b1 = c1; // is false
bool b2 = c2; // is true
if (!c1 && c2)
{
// Do stuff
}
}
Obviously the most notorious use might be using it to convert one of your classes to another of your classes. But using them with basic types is worth a consideration as well... and I see it mentioned quite rarely.
It's an implicit conversion operator (as opposed to an Explicit operator, which requires the (type) conversion syntax)
My two cents.
This is useful in Unit testing an immutable entity to be used with Builder Pattern.
Say you have Employee domain object defined in an immutable way. We do this typically when want to adhere to DDD style.
public class Employee
{
public Employee(int id, string firstname, string lastname, DateTime birthdate, string street)
{
this.ID = id;
this.FirstName = firstname;
this.LastName = lastname;
this.BirthDate = birthdate;
this.Street = street;
}
public int ID { get; private set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
public DateTime BirthDate { get; private set; }
public string Street { get; private set; }
public string getFullName()
{
return this.FirstName + " " + this.LastName;
}
public int getAge()
{
DateTime today = DateTime.Today;
int age = today.Year - BirthDate.Year;
if (BirthDate > today.AddYears(-age))
age--;
return age;
}
}
Now you can have an employee builder like the following(inside of the test project). Notice in the end, we have this implicit operator.
public class EmployeeBuilder
{
private int id = 1;
private string firstname = "first";
private string lastname = "last";
private DateTime birthdate = DateTime.Today;
private string street = "street";
public Employee Build()
{
return new Employee(id, firstname, lastname, birthdate, street);
}
public EmployeeBuilder WithFirstName(string firstname)
{
this.firstname = firstname;
return this;
}
public EmployeeBuilder WithLastName(string lastname)
{
this.lastname = lastname;
return this;
}
public EmployeeBuilder WithBirthDate(DateTime birthdate)
{
this.birthdate = birthdate;
return this;
}
public EmployeeBuilder WithStreet(string street)
{
this.street = street;
return this;
}
public static implicit operator Employee(EmployeeBuilder instance)
{
return instance.Build();
}
}
Now you can have a employee test class like the following.
public class EmployeeTest
{
[Test]
public void GetFullNameReturnsCombination()
{
// Arrange
Employee emp = new EmployeeBuilder().WithFirstName("Vivek").WithLastName("Koppula");
// Act
string fullname = emp.getFullName();
// Assert
Assert.That(fullname, Is.EqualTo("Vivek Koppula"));
}
[Test]
public void GetAgeReturnsCorrectValue() {
// Arrange
Employee emp = new EmployeeBuilder().WithBirthDate(new DateTime(1983, 1,1));
// Act
int age = emp.getAge();
// Assert
Assert.That(age, Is.EqualTo(DateTime.Today.Year - 1983));
}
}
This makes writing unit tests easier by enabling us to construct the employee just with required parameters.
For example in the first test, we are only concerned with first name and last name. So for the first case, we don't have to be bothered by age and street.
Similarly for the second case, we are concerned with age and nothing else.
Article References.
flexible-and-expressive-unit-tests-with-the-builder-pattern
improve-tests-with-the-builder-pattern-for-test-data

Categories