I have code like below. Interface with default implementation. And the user who uses this interface. But for some reason in the switch case my code uses the default implementation of the interface for the "Name' instead of the class implementation. What should i change to see "Ben" in console?
namespace ConsoleApp1
{
public interface IUser
{
// Interface with default implementation
public string Name { get => "Tom"; }
}
// User using this interface
public class BenUser : IUser
{
public string Name = "Ben";
}
public static class MainClass
{
public static void ShowName(IUser user)
{
switch (user.Name)
{
case "Ben": // I expected the code to run here
Console.WriteLine("Ben");
break;
case "Tom": // But the code goes here
Console.WriteLine("Tom");
break;
}
}
static void Main()
{
// Create a user with Name "Ben"
var ben = new BenUser();
ShowName(ben); // In console i see "Tom" for some reason
}
}
}
I can't figure out why the code is behaving like this.
CodePudding user response:
As mentioned in comments, you need to implement the interface using the same shape in your class - as a property with a get.
public interface IUser
{
// Interface with default implementation
public string Name { get => "Tom"; }
}
// User using this interface
public class BenUser : IUser
{
public string Name { get => "Ben"; }
}
public static class MainClass
{
public static void ShowName(IUser user)
{
switch (user.Name)
{
case "Ben": // I expected the code to run here
System.Console.WriteLine("Ben");
break;
case "Tom": // But the code goes here
System.Console.WriteLine("Tom");
break;
}
}
static void Main()
{
// Create a user with Name "Ben"
var ben = new BenUser();
ShowName(ben); // In console i see "Tom" for some reason
}
}
CodePudding user response:
This is my edit to show some more standard practices, please read through the comments and see if it makes anything more clear. The standard practice for creating members is to use accesslevel Type VariableName { get; set; }
namespace ConsoleApp1
{
public interface IUser
{
//denotes that this is set by construction, cannot be set afterwards
public string Name { get; }
}
// User using this interface
public class BenUser : IUser
{
// Standard 'getter' only member with a compiled return value
public string Name
{
get
{
return "Ben";
}
}
}
public class User : IUser
{
// private settable string to use with construction
private string _name;
// constructor
public User(string userName)
{
// sets the private variable to desired value
_name = userName;
}
// public 'getter' that returns the set value
public string Name
{
get
{
return _name;
}
}
}
public static class MainClass
{
public static void ShowName(IUser user)
{
Console.WriteLine(user.Name);
}
static void Main()
{
// Create a user with static Name "Ben"
var ben = new BenUser();
ShowName(ben);
// Create a user with variable Name set as "Carl"
var carl = new User("Carl");
ShowName(carl);
}
}
}
CodePudding user response:
The Name
in IUser
is a property while Name
in BenUser
is a field. With your code when we do user.Name
it calls the get
method defined in IUser
instead of getting value of Name field from BenUser
. Here is a sample implementation for fixing your bug.
public class BenUser : IUser
{
public string Name { get => "Ben"; }
}
I would recommend to not do it the way you are doing because Name
identifier has become embiguos