views:

144

answers:

5

I am working on making an address book in C# 2008. I need to be able to save the contacts and then later display them when the user asked for it. I also need to handle an exception when someone enters an unknown color when writing the person's favorite color. This is my code so far:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lab02
{
    class Program
    {


        static void Main(string[] args)
        {
            Contact contact = new Contact();

            Console.WriteLine("Please enter the person's name:");
            contact.Name = Console.ReadLine();

            Console.WriteLine("Please enter the person's e-mail address:");
            contact.Email = Console.ReadLine();

            Console.WriteLine("Please enter the person's favorite color:");
            string tempColor = Console.ReadLine();
            contact.Favoritecolor = (System.Drawing.KnownColor)(Enum.Parse(typeof(System.Drawing.KnownColor), tempColor));
            try
            {

            }
            catch 
            {

            }
            finally
            {
                Console.WriteLine("This is an unknown color. Please enter a known color");
            } 
        }
        class Color
        {
            enum clr
            // This is a list of colors for the user to pick from.
            {
                Red,
                Green,
                Blue,
                Yellow,
                Purple,
                Brown,
                Black,
                Crimson,
                White,
                Turqoise,
                Orange,
                Cyan,
                Pink,
                Gold,
                Silver,
                Bronze,
                Gray,
                Indigo,
                Rust
            }
        }
    }
        class Contact
        {
            //This string represents the person's Name.
            public string Name { get; set; }

            //This string represents the person's Email.
            public string Email { get; set; }

            public System.Drawing.KnownColor Favoritecolor 
            {
                get;
                set;
            }
        }
    }

Can anyone help me please?

A: 

The parsing gets moved into the try block, the catch block (which catches the exception) tells the user they need to enter something known. The finally block isn't required, so was removed:

try
{
    contact.Favoritecolor = (System.Drawing.KnownColor)(Enum.Parse(typeof(System.Drawing.KnownColor), tempColor));
}
catch(ArgumentException)
{
    Console.WriteLine("This is an unknown color. Please enter a known color");
}

The next part is that you need a loop until a valid colour has been entered

bool isValidColour = false;
while (!isValidColour)
{
    Console.WriteLine("Please enter the person's favorite color:");
    string tempColor = Console.ReadLine();
    try
    {
        contact.Favoritecolor = (System.Drawing.KnownColor)(Enum.Parse(typeof(System.Drawing.KnownColor), tempColor));
    isValidColour = true;
    }
    catch(ArgumentException)
    {
        Console.WriteLine("This is an unknown color. Please enter a known color");
    }
}

The above will keep looping around until a valid colour is entered.

I hope this helps.

Colin Mackay
Don't catch all exceptions.
Alan
Watch out! Alan's on a tear!
Ben M
Only trying to protect newby developers from learning bad habits from script kiddies.
Alan
I was trying to change as little code as possible.
Colin Mackay
I've updated the code to catch the specific exception.
Colin Mackay
A: 

Okay so this line:

   contact.Favoritecolor = (System.Drawing.KnownColor)(Enum.Parse(typeof(System.Drawing.KnownColor), tempColor));

Is where you are taking the value of color entered by the user, and parsing it into a known color, correct?

Seems like thats where you might run into problems. I'd see what type of exceptions can be thrown with that line, and properly handle them.

What happens if someone enters "rED" in the commandline? Should that thrown an exception? In your code example, will it throw an exception?

Additionally, you have a custom Color Class, with an enum type called "clr", but in your code, you're parsing your enum to the System.Drawing.KnownColor type. I would nix the custom class and use the built in type.

Alan
+1  A: 

Why not list all colors that the user can pick, with the Enum Value, then ask them to enter a number, try and convert it to an enum,then store it. If it fails to convert, let them know it's invalid.

Here's a little snippet to help. You'll need to make your enum public however.

Console.WriteLine("Here are a list of colors:");

foreach(Color.clr item in Enum.GetValues(typeof(Color.clr)))
{
    Console.WriteLine(string.Format("{0} - {1}",(int)item,item.ToString()));
}
Console.WriteLine("Please choose your color");
string colorInput = Console.ReadLine();
int colorValue = 0;
if(!int.TryParse(colorInput, out colorValue))
{
        Console.WriteLine(string.Format("{0} is not a valid number",colorInput));
        return;
}

// This will give an error if they've typed a number that wasn't listed
// So need to add a bit of checking here
Color.clr tempColor = (Color.clr)colorValue;

// Your code here
PostMan
Thank you, but when i put it in at the top I get this error: "A namespace does not directly contain members such as fields or methods" Where should I put this snippet?
This should be in Main() routine.
Alan
This is where you would ask for the color, I'll add a little bit more
PostMan
+1  A: 

You can also use the Reflection:

    public static class ColorInfo
    {
        private static readonly PropertyInfo[] PropertiesInfo;

        static ColorInfo()
        {
            PropertiesInfo = typeof(Color).GetProperties(BindingFlags.Public | BindingFlags.Static);
        }

        public static bool TryGetKnownColorFromString(string colorName, out KnownColor knowColor)
        {
            if (String.IsNullOrEmpty(colorName))//if wrong color name
            {
                knowColor = KnownColor.ActiveBorder;
                return false;
            }
            try
            {
                foreach (PropertyInfo property in PropertiesInfo)
                {
                    if (property.Name.Equals(colorName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        knowColor = ((Color)property.GetValue(null, null)).ToKnownColor();
                        return true;
                    }
                }
            }
            catch (Exception exc)
            {
                //catch GetValue & Equals methods exceptions
                if (!(exc is ArgumentException || exc is TargetException ||
                    exc is TargetParameterCountException ||
                    exc is MethodAccessException ||
                    exc is TargetInvocationException))
                {
                    //throw exc; //We don't want to lose information from StackTrace
                    throw; 
                }
            }
            knowColor = KnownColor.ActiveBorder;
            return false;
        }
    }

Simply test:

        string[] colors = { "reD", "AzUre", "Blue", "BlueViollet" };
        KnownColor knowColor;
        foreach (String color in colors)
        {
            if (ColorInfo.TryGetKnownColorFromString(color, out knowColor))
            {
                Console.WriteLine(knowColor.ToString());
            }
            else
            {
                Console.WriteLine("Color: {0} - not found !", color);
            }
        }

Output:

Red
Azure
Blue
Color: BlueViollet - not found !

Helpfull usings:

using System;
using System.Drawing;
using System.Reflection;
mykhaylo
If you really must rethrow from within an exception then use throw. Do not throw exc because it will reset the stack trace details and you lose where the original came from.
Colin Mackay
Good observation, thanks.
mykhaylo
+1  A: 

are you going to display them in the console app, Form App, does it need to persist the data or just hold in memory for the lifetime of the app, is your class "Contact" serializable

For simplicity sake and since this is homework make your class Contact Serializable

[Serializable]
public class Contact
{}

and use Binary serialization, I'm not going to write it all here but its fairlysimple look up Binary serialization and binaryformaters which can write a stream to disk for each contact or a list of contacts if you like. then if this is in the console app make a readline that accepts a "List" command and hits a method that iterates them and displays the properties for each contact.

Thats as far as I will go for writing your homework unless you pay me

Brandon Grossutti
It needs to persist the data and display it in the app
Persist them where? Go ask the teacher where he wants them. You can then ask a better question.
John Saunders
In a .dll file located in the folder
The teacher does **not** want the addresses persisted in a DLL. Do you even _have_ the assignment with you?
John Saunders