Calling method inside a method in Interface c# - c#

How to call a method inside a method in same class when using interface in c#? I got error when tried access through (object as baseclass).method
interface IAccount
{
string fullName{get;set;}
void Balance();
}
public class User : IAccount
{
public string fullName { get; set; }
public int balance = 10000;
public User(string firstName, string lastName)
{
fullName = firstName + lastName;
}
public void IAccount.Balance()
{
Console.WriteLine("Account balance-" + this.balance);
}
public void MyBalance()
{
Console.WriteLine(" My balance");
IAccount.Balance();
}
}

Try to remove the both IAccounton from public void Balance() and inside public void MyBalance()
interface IAccount
{
string fullName{get;set;}
void Balance();
}
public class User : IAccount
{
public string fullName { get; set; }
public int balance = 10000;
public User(string firstName, string lastName)
{
fullName = firstName + lastName;
}
public void Balance()
{
Console.WriteLine("Account balance-" + this.balance);
}
public void MyBalance()
{
Console.WriteLine(" My balance");
Balance();
}
}
Output:
Account balance-10000
My balance
Account balance-10000

When you create a method which is named InternfaceName.MethodName it is called Explicit interface implementation.
What it means is that that method is accessible only through a reference of the interface type.
So... How can you call to that method from within the class? Cast this to the interface type!
public void MyBalance()
{
Console.WriteLine(" My balance");
((IAccount)this).Balance();
}

Related

delegate method returns a null value

For the past two hours I've been trying to experiment with delegates / events - my aim is to inform users with both the previous book name and new book as a new book name is set.
However, in all cases in my Abstract class, NameChanged(args.ExistingName, args.NewNames); returns null. I can't seem to figure out why, I have tried manually passing through two string params yet visual studio throws an error stating that NameChanged contains a null value.
internal interface Iinterface
{
void AddContact(string name, string number);
void RemoveContact(string name);
void RetrieveContacts();
void RetrieveByName(string name);
void RetrieveByNumber(string number);
string Name { get; set; }
}
public abstract class Abstract : Iinterface
{
public abstract void AddContact(string name, string number);
public abstract void RemoveContact(string name);
public abstract void RetrieveContacts();
public abstract void RetrieveByName(string name);
public abstract void RetrieveByNumber(string number);
public string Name{
get
{
return _name;
}
set
{
NameChangedEventArgs args = new NameChangedEventArgs();
args.ExistingName = _name;
args.NewName = value;
NameChanged(args.ExistingName, args.NewName); // this refers to the abstract class?
_name = value;
}
}
public NameChangedEventHandler NameChanged; // I presume here we're taking an instance of the delegate method.
protected string _name;
}
public class PhoneBook : Abstract
{
public PhoneBook()
{
_name = "phone book name";
}
public override void AddContact(string name, string number)
{
contacts.Add(name, number);
}
public override void RemoveContact(string name)
{
contacts.Remove(name);
}
public override void RetrieveContacts()
{
foreach (KeyValuePair<string, string> entry in contacts)
{
Console.WriteLine("Name : {0} Number : {1}", entry.Key, entry.Value);
}
}
public override void RetrieveByName(string name)
{
foreach(KeyValuePair<string, string> entry in contacts)
{
if(entry.Key == name)
{
Console.WriteLine("Name : {0} Number : {1}", entry.Key, entry.Value);
}
}
}
public override void RetrieveByNumber(string number)
{
foreach(KeyValuePair<String,string> entry in contacts)
{
if (entry.Value == number)
{
Console.WriteLine("Name : {0} Number : {1}", entry.Key, entry.Value);
}
}
}
Dictionary<string, string> contacts = new Dictionary<string, string>();
}
public class NameChangedEventArgs : EventArgs
{
public string ExistingName { get; set; }
public string NewName { get; set; }
}
{
// public delegate void NameChangedEventHandler(object sender, NameChangedEventArgs args);
public delegate void NameChangedEventHandler(string existingName, string newName);
}
class Program
{
static void Main(string[] args)
{
PhoneBook book = new PhoneBook();
setName(book);
addContact(book);
retrieveByName(book);
retrieveByNumber(book);
book.NameChanged = new NameChangedEventHandler(OnNameChanged); // call OnNameChanged whenever someone invokes this delegate
Console.ReadLine();
/* book.retrieveContacts(); */
}
private static void setName(PhoneBook book)
{
book.Name = "book name";
Console.WriteLine(book.Name);
}
private static void retrieveByNumber(PhoneBook book)
{
book.RetrieveByNumber("0323242389");
}
private static void retrieveByName(PhoneBook book)
{
book.RetrieveByName("james");
}
private static void addContact(PhoneBook book)
{
book.AddContact("james", "0151289");
book.AddContact("Bob", "0323242389");
book.AddContact("Hannah", "34234");
}
static void OnNameChanged(string existingName, string newName)
{
Console.WriteLine($"Gradebook changing name from {existingName} to {newName}");
}
}
For registering a delegate or event with a method, the following is the syntax for it:
book.NameChanged+= new NameChangedEventHandler(OnNameChanged);
and Secondly you should not be invoking it blindly at invoking side.
you should be checking if someone has subscribed to it or any method is assigned to it like:
if(NameChanged !=null)
NameChanged(args.ExistingName, args.NewName);
or in c# 6:
NameChanged?.Invoke(args.ExistingName, args.NewName);
Hope it helps you.

Multiple Interfaces

I am trying to input 2 interfaces to a class so that I may return information from them, in this case, an age and a name. However I have run into a problem where my C1 class does not have a matching return type of int, and I don't understand what to do now as any examples I've seen only had 1 interface or multiple classes. Here is what I have so far:
interface IWhatsMyAgeAgain
{
int GetAge();
}
interface ISayMyName
{
string GetName();
}
class C1 : IWhatsMyAgeAgain, ISayMyName
{
public int Age;
public string Name;
public string GetName() {return Name;}
public int GetAge() {return Age;}
}
class Program
{
static void PrintInfo (IWhatsMyAgeAgain item, ISayMyName Item )
{
Console.WriteLine("Name: {0}, Age {1}", Item.GetName(), item.GetAge() );
}
static void Main()
{
C1 a = new C1() { Name = "Tom", Age = 29 };
Console.ReadLine();
}
}
IWhatsMyAgeAgain's GetAge method returns int but your class returns string, change it to this:
class C1 : IWhatsMyAgeAgain, ISayMyName
{
public int Age;
public string Name;
public string GetName() { return Name; }
public int GetAge() { return Age; }
}

C# Adding Derived classes to a collection of Base classes

public abstract class Person
{
protected string name;
public Person(string firstName)
{
name = firstName;
}
{
public BusinessPerson : Person
{
public BusinessPerson(string newName) : base(newName)
{
}
}
public class Group : CollectionBase
{
public void Add(Person newPerson)
{
List.Add(newPerson);
}
}
int Main
{
Group VariousPeople = new Group();
VariousPeople.Add(new BusinessPerson("Jack")); // says invalid arguments
}
================================================================================
If I am correct shouldn't polymorphism allow me to store derived types in a container of
base types? Why doesn't this work for me?
It works fine for me. Your code in the question is missing some braces and things, but once fixed, it compiles and works fine on my compiler. Fixed code is below.
internal class Program
{
private static void Main(string[] args)
{
Group VariousPeople = new Group();
VariousPeople.Add(new BusinessPerson("Jack"));
}
}
public abstract class Person
{
protected string name;
public Person(string firstName)
{
name = firstName;
}
}
public class BusinessPerson : Person
{
public BusinessPerson(string newName)
: base(newName)
{
}
}
public class Group : CollectionBase
{
public void Add(Person newPerson)
{
List.Add(newPerson);
}
}

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;
}
}

Relationship between two interfaces and two classes.

So I want to design a team/player relationship like this: every player belongs to one team but since I wanted to practice with interfaces I made ITeam and IAthlete and then made BasketballTeam and BasketballPlayer.
Then I wrote this code:
public interface IAthlete
{
string GetName();
string GetSport();
}
public interface ITeam
{
void AddPlayer(IAthlete player);
IAthlete[] GetAthletes();
string GetName();
int GetNumberOfPlayers();
}
public class BasketballPlayer:IAthlete
{
private string name;
public string GetName()
{
return this.name;
}
public string GetSport()
{
return "Basketball";
}
public BasketballPlayer(string name)
{
this.name = name;
}
public void Run(int distance)
{
Console.WriteLine(this.name + " just ran " + distance.ToString() + " meters.");
}
public bool Shoot()
{
Console.WriteLine("Successful shot for " + this.name);
return true;
}
}
public class BasketballTeam: ITeam
{
BasketballPlayer[] players;
int numberOfPlayers;
private string name;
public void AddPlayer(BasketballPlayer player)
{
this.players[this.numberOfPlayers] = player;
this.numberOfPlayers++;
}
public IAthlete[] GetAthletes()
{
return this.players;
}
public string GetName()
{
return this.name;
}
public int GetNumberOfPlayers()
{
return this.numberOfPlayers;
}
public BasketballTeam(string name)
{
this.numberOfPlayers = 0;
this.name = name;
this.players = new BasketballPlayer[10];
}
}
class Program
{
static void Main(string[] args)
{
BasketballTeam bt = new BasketballTeam("MyTeam");
BasketballPlayer bp = new BasketballPlayer("Bob");
bt.AddPlayer(bp);
foreach (BasketballPlayer player in bt.GetAthletes())
{
Console.WriteLine(player.GetName());
}
foreach (IAthlete a in bt.GetAthletes())
{
Console.WriteLine(a.GetName());
}
}
}
But it won't compile because I'm using this:
public void AddPlayer(BasketballPlayer player)
in the BasketballPlayer instead of this
public void AddPlayer(IAthlete player)
I thought it should work because BasketballPlayer is an IAthlete.
And if I change it to IAthlete then I can make another class like this:
public class HockeyPlayer : IAthlete
{
private string name;
public string GetName()
{
return this.name;
}
public string GetSport()
{
return "Hockey";
}
public HockeyPlayer(string name)
{
this.name = name;
}
public void Run(int distance)
{
Console.WriteLine(this.name + " just ran " + distance.ToString() + " meters.");
}
}
and then do this in my main:
HockeyPlayer hp = new HockeyPlayer("Henry");
bt.AddPlayer(hp);
which is logically wrong because I'm adding HockeyPlayer to a BasketballTeam. Is it supposed to be like this and I should just be careful not to do that? What am I doing wrong? How do I show this using class diagrams? Does this lead to loose coupling?
You're trying to violate the Liskov Substitution Principle.
Anything that can be done with a supertype – such as adding a HockeyPlayer – can also be done with a subtype – including a BasketballTeam.
Instead, you should use generics:
class Team<TPlayer> where TPlayer : IAthlete {
public ReadOnlyCollection<TPlayer> Players { get; }
public string Name { get; }
public void AddPlayer(TPlayer player);
}
Here is some thoughts on your code. First, in C# you can use properties, instead of Get and Set methods.
public interface IAthlete
{
string Name { get; }
string Sport { get; }
}
With auto-properties you can ask compiler to generate back store for property. Also consider creating base class Player, which will hold implementation of Name and Sport properties.
public class Player : IAthlete
{
public Player(string name, string sport)
{
Name = name;
Sport = sport;
}
public string Name { get; private set; }
public string Sport { get; private set; }
}
Now when implementing some player, you can just pass values to base class constructor. And your custom players will hold only specific for them functionality (no code duplication). Also it's recommended to use string format, instead of concatenating strings:
public class BasketballPlayer : Player
{
public BasketballPlayer(string name)
: base(name, "Basketball")
{
}
public void Run(int distance)
{
Console.WriteLine("{0} just ran {1} meters.", Name, distance);
}
public bool Shoot()
{
Console.WriteLine("Successful shot for " + Name);
return true;
}
}
Now about teams. If you don't want to have FootballPlayers in your BasketballTeam, then you should create parametrized team. Also consider using IEnumerable:
public interface ITeam<TPlayer>
where TPlayer : IAthlete
{
void AddPlayer(TPlayer player);
IEnumerable<TPlayer> Players { get; }
string Name { get; }
int NumberOfPlayers { get; }
}
Again, for common functionality you can create base class. Keep in mind, that you should check how many players currently in your team before adding new player.
public class Team<TPlayer> : ITeam<TPlayer>
where TPlayer : IAthlete
{
private readonly List<TPlayer> _players = new List<TPlayer>();
public Team(string name, int teamSize)
{
Name = name;
TeamSize = teamSize;
}
public void AddPlayer(TPlayer player)
{
if (_players.Count == TeamSize)
throw new Exception("Players number exceeded");
_players.Add(player);
}
public string Name { get; private set; }
public int TeamSize { get; private set; }
public IEnumerable<TPlayer> Players
{
get { return _players; }
}
public int NumberOfPlayers
{
get { return _players.Count; }
}
}
And custom team implementation becomes really easy. You just tell which type of players it will have, and pass to base team implementation team name and size of team.
public class BasketballTeam : Team<BasketballPlayer>
{
public BasketballTeam(string name)
: base(name, 10)
{
}
}
Now your program works like a charm:
class Program
{
static void Main(string[] args)
{
BasketballTeam bt = new BasketballTeam("MyTeam");
BasketballPlayer bp = new BasketballPlayer("Bob");
bt.AddPlayer(bp);
foreach (BasketballPlayer player in bt.Players)
{
Console.WriteLine(player.Name);
}
foreach (IAthlete a in bt.Players)
{
Console.WriteLine(a.Name);
}
}
}
Logically ,
These should be your base classes : Team , Player
These should be your derived classes : BasketballTeam , BasketballPalyer
These should be interfaces on Player : IPlay() , IRun , IGetName etc.. whichever applicable
and so on...
Guideline : Verbs suits more good on interfaces and Noun suits good on classes. Noun in the requirement best suits for Class in the code.
SLaks is correct. You could add a generic constraint to your ITeam to not accept all players, but just those of one type:
public interface ITeam<T> where T : IAthlete
{
void AddPlayer(T player);
IAthlete[] GetAthletes();
// or: T[] GetAthletes();
string GetName();
int GetNumberOfPlayers();
}
A BasketballTeam implementation could look like:
public class BasketballTeam : ITeam<BasketballPlayer>
{
BasketballPlayer[] players;
// […]
public void AddPlayer(BasketballPlayer player)
{
this.players[this.numberOfPlayers] = player;
this.numberOfPlayers++;
}
public IAthlete[] GetAthletes()
{
return this.players;
}
// or:
// public BasketballPlayer[] GetAthletes()
// {
// return this.players;
// }
// […]
}
If your interfaces are meant to be used by variety of games, it seems that you are missing the Game here and perhaps need to use Generics:
public interface IGame
{
string Name {get;}
...
}
public class Bastketball : IGame
{
...
}
public interface ITeam<TGame> where TGame: class, IGame
{
void AddPlayer(IPlayr<TGame> player);
...
}
public interface IPlayer<TGame> where TGame: class, IGame
{
...
}
This will prevent from hockey player to be added to Basketball team.

Categories