Создание метода доступа для свойств частного объекта - перечисление?

Я изучаю методы доступа и перечисление. Я написал общедоступный класс «Автомобиль» в пространстве имен «Транспортные средства» и установил частные свойства, такие как _manufacturer, _model, _year и _color. Я хотел бы написать один метод для доступа к свойствам, а другой - для их установки / обновления. Это мой класс:

using System;

namespace Vehicles
{
    public class Car
    {
        private string _manufacturer;
        private string _model;
        private string _year;
        private string _color;

        public void honkHorn()
        {
            // Add argument for a file name?
            // Code here to play a WAV file?
            MessageBox.Show("Honk!");
        }

        public string getCarInfo(string whichProperty)
        {
            switch (whichProperty)
            {
                case ("manufacturer"):
                   return _manufacturer;
                case ("model"):
                    return _model;
                case ("year"):
                    return _year;
                case ("color"):
                    return _color;
                default:
                    return null;
            }
        }

        public void setCarInfo(string whichProperty, string newValue)
        {
            switch (whichProperty)
            {
                case ("manufacturer"):
                    _manufacturer = newValue;
                    break;
                case ("model"):
                    _model = newValue;
                    break;
                case ("year"):
                    _year = newValue;
                    break;
                case ("color"):
                    _color = newValue;
                    break;
            }
        }
    }
}

А это моя форма:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Vehicles;

namespace CS_Enumeration
{
    public partial class Form1 : Form
    {
        public Car myCar = new Car();

        public Form1()
        {
            InitializeComponent();

            myCar.setCarInfo("manufacturer", "Ford");
            labelManfValue.Text = myCar.getCarInfo("manufacturer");

            myCar.setCarInfo("model", "Ranger");
            labelModelValue.Text = myCar.getCarInfo("model");

            myCar.setCarInfo("year", "2012");
            labelYearValue.Text = myCar.getCarInfo("year");

            myCar.setCarInfo("color", "Blue");
            labelColorValue.Text = myCar.getCarInfo("color");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            myCar.honkHorn();
        }
    }
}

Действительно ли это лучший способ написать единственный метод, который может получить / установить? Сначала я попытался привести строковое значение, которое соответствует имени свойства объекта и вернуть фактическое свойство, но это не работает (если кто-то не знает, как преобразовать строку в свойство объекта?).

Спасибо за ответы. Это все упражнения из книги, которую я читаю. Дело доходит до того, что не все должно быть публичным, но и не все должно быть приватным. Итак, как мне узнать, когда что-то должно / не должно быть публичным / частным? Похоже, книга ведет меня в неверном направлении относительно того, что такое хороший дизайн кода. У кого-нибудь есть предложения по книгам для изучения хороших практик проектирования кодирования для Visual C #?


person spickles    schedule 02.03.2012    source источник
comment
Зачем тебе это делать? Imo, это ужасный дизайн - просто выставьте свойства. Вдобавок к этому вы потеряли всю безопасность типов в своем текущем подходе, и любая опечатка вызовет исключение времени выполнения.   -  person BrokenGlass    schedule 02.03.2012
comment
Смотрите редактирование моего исходного сообщения. Все это основано на книге C #, которую я читаю, и рекомендация заключалась в использовании частных переменных. Из того, что мне пришлось пройти для получения / установки свойств, я вижу, что это немного смешно. Спасибо.   -  person spickles    schedule 02.03.2012
comment
Что это за книга? Мы хотели бы проигнорировать это и, возможно, посмеяться над этим.   -  person John Saunders    schedule 02.03.2012
comment
@JohnSaunders Head First C #   -  person spickles    schedule 03.03.2012
comment
Спасибо. Ясно, что прежде всего голова, а не мозг.   -  person John Saunders    schedule 03.03.2012


Ответы (2)


Не делай этого.

Вместо этого используйте общедоступные свойства, и вы получите безопасность типов и гораздо более выразительное использование вашего класса. В вашем текущем подходе любая опечатка в строке имени свойства вызовет исключение времени выполнения вместо ошибки компиляции.

Просто используйте свойства:

public class Car
{
   public string Manufacturer {get; set;}
   public string Model {get; set;}
   public string Year {get; set;}
   public string Color {get; set;}

  //..
}

Теперь вы можете просто получить доступ к свойствам напрямую:

myCar.Manufacturer  = "Ford";
labelManfValue.Text = myCar.Manufacturer;

Также вы должны определить конструктор, который полностью инициализирует объект Car, иначе у вас могут быть установлены некоторые свойства, а другие нет.

person BrokenGlass    schedule 02.03.2012
comment
Чтобы определить конструктор, нужно ли мне просто добавить свойства к определению класса, или это будет иметь какое-то отношение к перечислению? Конструктор будет выглядеть примерно так: public class Car(string manufacturer) - person spickles; 02.03.2012
comment
Да - примерно так. Что касается публичных / частных дебатов - на основе вашего примера ясно, что вам нужен доступ для чтения к этим свойствам извне, поэтому, по крайней мере, свойство только для чтения - но также свойства компилируются в методы получения / установки с помощью поле поддержки того же типа - что в основном эквивалентно тому, что вы пытались достичь с помощью метода установки. - person BrokenGlass; 02.03.2012
comment
Хорошо, похоже, я хочу сделать именно то, что вы показали с помощью {get; установленный;}. Я считаю, что могу инициализировать переменные при создании экземпляра объекта, даже если я не определяю конструктор, верно? Что-то вроде Car porche = new Car({ _speed = fast; }) - person spickles; 03.03.2012

Вы можете сделать это с помощью отражения:

void Main()
{
    var foo = new Foo();
    foo.Set("bar","test");
    Console.WriteLine(foo.Get("bar"));
}
class Foo
{
    string bar;
    string bop;

    public void Set(string name, string value)
    {
        GetType().GetField(name, BindingFlags.NonPublic|BindingFlags.Instance)
                 .SetValue(this, value);
    }

    public string Get(string name)
    {
        return (string)GetType().GetField(name, BindingFlags.NonPublic|BindingFlags.Instance)
                                .GetValue(this);
    }
}

Но это очень плохая идея.

person porges    schedule 02.03.2012