I have this generic method to solve the fizzbuzz quiz but when I use the class instance as a parameter to the method. I get an empty output. Can anyone help out with this.
if input is divisible by 3 output Fizz
divisible by 5 output = Buzz
3 & 5 = FizzBuz<
private static string FizzBuzz<T>(T item)
{
int itemLength = item.ToString().Length;
string output = "";
if (itemLength % 3 == 0)
{
output += "Fizz";
}
if (itemLength % 5 == 0)
{
output += "Buzz";
}
return output;
}
here is a class
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
//in the main method class
static void Main(string[] args)
{
string result = (FizzBuzz("tests"));
Console.WriteLine($"Tests: {result}");
result = FizzBuzz(223);
Console.WriteLine($"223:{result}");
result = FizzBuzz ( new UserModel { FirstName = "Vic", LastName = "Okpas"});
Console.WriteLine($" user model: {result}");
}
output:
Tests: Buzz
223: Fizz
user model:
the user model is supposed to output Fizz because the first name has 3 letters. Can anyone help me figure out what i am doing wrong.
The key is ToString()
in int itemLength = item.ToString().Length;
Let's restructure your program a little bit to see what's happening.
static string FizzBuzz<T>(T item)
{
int itemLength = item.ToString().Length;
string output = "";
if (itemLength % 3 == 0)
{
output += "Fizz";
}
if (itemLength % 5 == 0)
{
output += "Buzz";
}
Console.WriteLine($"'{item.ToString()}' -> {itemLength} -> '{output}'");
return output;
}
Now the following code
FizzBuzz("tests");
FizzBuzz(223);
FizzBuzz(new UserModel
{
FirstName = "Vic",
LastName = "Okpas"
});
prints
'tests' -> 5 -> 'Buzz'
'223' -> 3 -> 'Fizz'
'UserModel' -> 9 -> 'Fizz'
The issue is that ToString()
for a class gives its name.
With this knowledge, if you insist that your FizzBuzz should use ToString().Length
as the number all we need to do teach the ItemModel
class how to return FirstName
from ToString()
:
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return FirstName;
}
}
Now the output for
FizzBuzz(new UserModel
{
FirstName = "Vic",
LastName = "Okpas"
});
is
'Vic' => 3 -> 'Fizz'
FizzBuzz methods cannot really be made generic because their input really is a number and nothing else. What this number is for a given type is something that cannot be decided inside the method.
This is more sensible in my opinion:
static string FizzBuzz(int x)
{
string output = "";
if (x% 3 == 0)
...
}
// and then
var userModel = new UserModel
{
FirstName = "Vic",
LastName = "Okpas"
}
FizzBuzz(userModel.FirstName.Length);
If you really wish to make you FizzBuzz more generic you could make it accept and interface.
static string FizzBuzz(IForFizzBuzz item)
{
int x = item.NumberForFizzBuzz;
string output = "";
if (x % 3 == 0)
{
output += "Fizz";
}
if (x % 5 == 0)
{
output += "Buzz";
}
Console.WriteLine($"'{x} -> '{output}'");
return output;
}
public class UserModel: IForFizzBuzz
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int NumberForFizzBuzz => FirstName.Length;
}
public interface IForFizzBuzz {
public int NumberForFizzBuzz {get; }
}
and then you can call it with your model
FizzBuzz(new UserModel
{
FirstName = "Vic",
LastName = "Okpas"
});
Since all types in C# provide ToString()
your version of the method doesn't benefit from being generic and could just accept an object
static string FizzBuzz(object item)
{
int itemLength = item.ToString().Length;
string output = "";
...