Okay, so what I'm trying to do here is create an array of classes. My class TEAMLEADER is derived from an abstract class, Employee. However when I try to create an instance of TEAMLEADER in Main, I get an error message saying TEAMLEADER cannot be found.
namespace Lab3
{
public abstract class Employee
{
protected string EmployeeName;
protected int EmployeeNumber;
protected double WeeklySalary;
public Employee (string EmployeeName, int EmployeeNumber, double WeeklySalary)
{
this.EmployeeName = EmployeeName;
this.EmployeeNumber = EmployeeNumber;
this.WeeklySalary = WeeklySalary;
}
public Employee(string EmployeeName)
{
assignID(EmployeeNumber);
}
public override string ToString()
{
return EmployeeName + " " + EmployeeNumber + " " + WeeklySalary;
}
protected virtual double CalcSalary()
{
return CalcSalary();
}//"Virtual" is a keyword that says, "This can be overriden in the derived class."
private static int assignID(int EmployeeNumber)
{
EmployeeNumber.ToString();
EmployeeNumber++;
return EmployeeNumber;
}
}
class Program
{
static void Main(string[] args)
{
Employee[] workerarray = new Employee[4];
workerarray[0] = new TeamLeader("Rachel", 18, 1000000.00, 52000000.00, true);
}
}
}
In a separate class/tab is the TEAMLEADER class.
public class TeamLeader:Employee
{
protected double AnnualSalary;
protected bool WeeklyGoal;
public override void CalcSalary()
{
if (WeeklyGoal == true)
{ CalcSalary = (AnnualSalary / 52) * 1.10; }
else (CalcSalary = AnnualSalary / 52);
}
public TeamLeader(string EmployeeName, int EmployeeNumber, double WeeklySalary, double AnnualSalary, bool WeeklyGoal):base(EmployeeName, EmployeeNumber, WeeklySalary)
{
this.WeeklyGoal = WeeklyGoal;
this.AnnualSalary = AnnualSalary;
}
}
The problem is in my main method. I can't understand why I can't create an instance of TeamLeader. It's not an abstract class, so shouldn't Main be able to recognize it and create an instance?
Have you tried adding:
using Lab3;
to the top of your Main class file?
Try this
Make sure you added namespace Lab3 to the top of your file where TeamLeader class is located. Then add this line of code using Lab3; to the top of your main file.
If that does not work for you try this.
Maby you added TeamLeader class to a different assembly
To solve this.
Click on References in the assembly where your main is located
Click on Add Reference
Click on Projects > Solutions and add your assembly
Please let me know if it worked or not
Do you have a public default constructor in your class?
public Employ()
{
}
When the command
Employee[] workerarray = new Employee[4];
is executed, it needs to create 4 new objects of type Employ, but those cannot be created because there is not a parameter-less constructor.
Related
I have 2 classes:
public class Access
{
public class Job
{
public int Id { get; set; }
protected string JobName { get; set; }
}
}
Class2.cs
public class Full: Access.Job
{
}
Full ful = new Full();
Why I'm not able to access the ful.JobName member?
Because You are trying to access protected method from outside the class. Only public methods are available. You can access the property/variably/method that is protected, only in the inherited class, but not from outer code:
public class Full: Access.Job
{
public void mVoid()
{
Console.WriteLine(this.JobName);
}
protected void mProtVoid()
{
Console.WriteLine(this.JobName);
}
private void mPrivateVoid()
{
Console.WriteLine("Hey");
}
}
Full myFull = new Full();
myFull.mVoid(); //will work
myFull.mProtVoid(); //Will not work
myFull.mPrivateVoid(); //Will not work
If You need to get to the protected property, there are 2 ways (3 actually, but Reflection is the dirty way and should be avoided):
1. Make it public
If it will be set to public, it will be stil inherit and You can directly access it:
Full nFull = new Full();
Console.Write(nFull.JobName);
2. Make a "wrapper"/"facade"
Create new property or method, that will just access the hidden property and return it in expected format.
public class Full: Access.Job
{
public string WrappedJobName { get { return this.JobName; } }
public string WrappedJobName => this.JobName; //C# 6.0 syntax
}
Full mFull = new Full();
Console.WriteLine(mFull.WrappedJobName);
Bit of a complicated question, I apologize if it is something stupid that I've missed. I've tried many solutions and solved it in a way but now the Reference Number within Customer will not increment on the .csv file?
This is the initial reference number being held to be used by the factory...
abstract class ReferenceNo
{
static protected int _refNo;
static public int ReferenceNumber
{
get
{
return _refNo;
}
}
}
This is the factory which SHOULD increment the reference number...
class ReferenceNoFactory
{
static private int lastbookingrefno = 0; // Last used booking reference number.
static private int lastcustomerrefno = 0; // Last used customer reference number.
static public ReferenceNo FactoryMethod(string type)
{
if (type == "Booking")
{
lastbookingrefno++; // Create new booking reference number.
return new Booking(lastbookingrefno);
}
else if (type == "Customer")
{
lastcustomerrefno++; // Create a new customer reference number.
return new Customer(lastcustomerrefno);
}
else
return null; // Default, only a booking or customer reference number can be created.
// Nothing else should be returned, or null.
}
}
This is the first part of the Customer class which gets the reference number and uses a logger instance to save it to the .csv file...
class Customer : ReferenceNo
{
static private string FirstName;
static private string LastName;
static private string Address;
public Customer(int refNo)
{
ReferenceNo._refNo = refNo;
}
static public void LogFile()
{
ReferenceNoFactory.FactoryMethod("Customer");
CustomerLogger firstlogger = CustomerLogger.Instance;
firstlogger.log(Customer.ReferenceNumber, Customer.firstname, Customer.lastname, Customer.address);
}
And this is the logger which holds the filepath etc...
private static CustomerLogger instance;
private CustomerLogger() {}
public static CustomerLogger Instance
{
get
{
if ( instance == null)
{
instance = new CustomerLogger();
}
return instance;
}
}
public void log(int custnum, string firstname, string lastname, string address)
{
System.IO.File.AppendAllText("F:\\Software Dev 2\\Coursework 2\\Mia-CourseWork2\\Customers.csv", "CustRefNum," + custnum + ",FirstName, " + firstname + ",LastName," + lastname + ",Address," + address + "\n");
}
The Reference number stays 1?...
I'm having trouble replicating your problem, I ran your example:
static void Main(string[] args)
{
Customer.LogFile();
Customer.LogFile();
}
I modified the logger to be simply:
public void log(int custnum, string firstname, string lastname, string address)
{
Console.WriteLine(Customer.ReferenceNumber);
}
I get the following output:
1
2
I would suggest that you take a more conventional approach to your custom class and simply have non-static properties. If you want to store the last booking reference and the last customer reference I suggest you do use a property on the ReferenceNoFactory.
I need the separate classes for Xml Serialization. I'd like to know if there is a simpler way for the inheriting BuildingDetail class to acquire the property values from the parent Building class.
Parent Class
public class Building
{
public int BuildingId;
public string BuildingName;
protected Building()
{
}
private Building(int buildingId, string buildingName)
{
BuildingId = buildingId;
BuildingName = buildingName;
}
public static Building Load(int buildingId)
{
var dr = //DataRow from Database
var building = new Building(
(int) dr["BuildingId"],
(string) dr["BuildingName"]);
return building;
}
}
Inheriting Class
public class BuildingDetail : Building
{
public BaseList<Room> RoomList
{
get { return Room.LoadList(BuildingId); }
}
protected BuildingDetail()
{
}
// Is there a cleaner way to do this?
private BuildingDetail(int buildingId, string buildingName)
{
BuildingId = buildingId;
BuildingName = buildingName;
}
public new static BuildingDetail Load(int buildingId)
{
var building = Building.Load(buildingId);
var buildingDetail = new BuildingDetail(
building.BuildingId,
building.BuildingName
);
return buildingDetail;
}
}
Thanks.
Firstly, change your base class constructor access modifier to protected. And then you can call base class constructor with base keyword:
private BuildingDetail(int buildingId, string buildingName)
: base(buildingId, buildingName)
{
...
}
It will call the base constructor first. Also if you don't put the :base(param1, param2) after your constructor, the base's empty constructor will be called.
This was from my university C# - windows forms exam, im trying to resolve some old subjects, but i seem to find myself stuck in this situation. This is my code:
abstract class CarFile
{
private string marca;
private readonly string serie;
public CarFile(string marca, string serie)
{
this.marca = marca;
this.serie = serie;
}
public string GetMarca
{
get { return this.marca; }
set { this.marca = value; }
}
public string GetSerie
{
get { return this.serie; }
}
public abstract string GetDescriere();
}
Then I have to do this:
my second class called ServiceFile : CarFile, ICloneable. in this class i have an array or list of strings called RepairComands which contains the necessary repairs.
- a private atribute called "motor" which can only take the following vallues {gas,gpl,hibrid} .
- a constructor which throws a generic exception if "serie==null"
-overrides the abrstract method getDescriere() to return the complete description of the car file
this is my code:
public class MyException : System.Exception
{
public MyException(string mesaj) : base(mesaj) { }
}
class ServiceFile : CarFile, ICloneable, IComparable, IReparabil
{
string[] RepairComands;
private enum motor { motorina, benzina, GPL, electric, hibrid };
public ServiceFile(string serie, string marca, string[] RepairComands):base(serie,marca){
if (serie == null)
{
throw new MyException("MESAJ");
}
this.RepairComands = RepairComands;
}
//not sure if this is correct
public override string GetDescriere()
{
string msj = string.Format("the car {0} with serial {1} and necess. repairs {2}", this.GetMarca, this.GetSerie, this.RepairComands);
return msj;
}
public object Clone()
{
ServiceFile clone = new ServiceFile(this.GetSerie, this.GetMarca, this.RepairComands);
return clone;
}
//implemented IComparable to be able to compare here 2 files by the number of repairs needed
public int CompareTo(object obj)
{
ServiceFile altafisa = (ServiceFile)obj;
if (this.RepairComands != altafisa.RepairComands)
return 1;
else return 0;
}
//overloads ToString to return the complete file description
public override string ToString()
{
return this.GetMarca + " "+ this.GetSerie + " " + this.RepairComands;
}
}
}
so far so good. this actually works.
but my problem comes now:
I have to define the interface IRep which contains 2 methods : void RepairCar() and void AddRepair(string repair).
THen ServiceFile class implements : IRep, and the function RepairCar() will be used for removing the last repair from the collection RepairComands
and the function AddRepair(string repair) will be used to add a repair in the collection RepairComands.
(For allowing the access to the private list of Repairs we should overload the index operator[] )
Thank you so much for your help, I'm a beginnes in C# and just wanted to understand better this subject that was given in my class so i could learn
Thank you
I need to create an inherritance of an Event as a SwimmingEvent however I'm receiving an error that the constructor doens't contain 0 arguments, the problem is I don't know which arguments are meant to be passed through. Any help would be greatly appreciated.
//Base Class
class Event
{
private string m_evName;
private string m_evDate;
private string m_evTime;
private string m_evFee;
private string m_evVenue;
private List<Athlete> m_athletes;
public String EvName { get { return m_evName; } }
public String EvDate { get { return m_evDate; } }
public String EvTime { get { return m_evTime; } }
public String EvFee { get { return m_evFee; } }
public String Venue { get { return m_evVenue; } }
//Getters/Setters - Making private variables avilable in public space through class method
public Event(String EvName, String EvDate, String EvTime, String EvFee, String EvVenue)
{
m_evName = EvName;
m_evDate = EvDate;
m_evTime = EvTime;
m_evFee = EvFee;
m_evVenue = EvVenue;
m_athletes = new List<Athlete>();
}
}
//child class
class SwimmingEvent : Event
{
private String m_distance;
private String m_inOutVar;
public SwimmingEvent(String Distance, String InOrOut)
{
m_distance = Distance;
m_inOutVar = InOrOut;
}
}
Since SwimmingEvent is an Event, you need to pass all arguments that you pass to the Event's constructor to the constructor of SwimmingEvent, and then some:
public SwimmingEvent(String EvName, String EvDate, String EvTime, String EvFee, String EvVenue, String Distance, String InOrOut)
: base (EvName, EvTime, EvFee, EvVenue, Distance) {
m_distance = Distance;
m_inOutVar = InOrOut;
}
using System;
public class MyBase
{
int num;
public MyBase(int i )
{
num = i;
Console.WriteLine("in MyBase(int i)");
}
public int GetNum()
{
return num;
}
}
public class MyDerived: MyBase
{
// This constructor will call MyBase.MyBase(int i)
***//You are missing this.***
public MyDerived(int i) : base(i)
{
}
}
You need to pass all arguments back to your parent.
class SwimmingEvent : Event
{
private String m_distance;
private String m_inOutVar;
public SwimmingEvent(String Distance, String InOrOut, string evName) : base (evName,"b","c", "d", "e")
{
m_distance = Distance;
m_inOutVar = InOrOut;
}
}
May be something like this:
public class Event
{
public Event() {} // public empty ctor
....
....
}
and derived
public class SwimmingEvent : Event
{
}
In this way you will avoid (assuming that is what you want) the compile time error, as a ctor with empty arguments list is already present in base class.
If this is not what you're searching for, please clarify.
in C#, before constructor of derived class (such as SwimmingEvent constructor) is called, constructor of base class (Event class) must be called too. Arguments of call to base class's constructor are usually specified using "base" keyword like this:
class SwimmingEvent : Event
{
....
public SwimmingEvent(String Distance, String InOrOut)
:base(/*Arguments for base class constructor*/)
{
//Constructor of derived class
}
}
if you omit ":base(...)", compiler assumes calling parameterless constructor of base class, such as if you write ":base()". But there is no parameterless constructor in base class, so you get the error.
You must either create parameterless constructor in Event class, or add "base" keyword and specify arguments for calling existing Event class's constructor in SwimmingEvent's declaration.