Можно ли инициализировать общедоступные свойства класса с использованием другого типа в С#?
В Java у меня может быть такой объект:
public class MyObject {
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public void setDate(String date) {
this.date = parseDateString(date);
}
private Date parseDateString(String date) {
// do magic here
return dateObj;
}
}
Это хорошо, потому что у меня есть один getter для моих свойств и несколько настроек. Я могу установить свойство "date", передав либо объект Date, либо String, и дайте классу понять его.
В С# это похоже на то, что все немного отличается. Я могу это сделать:
public class MyObject
{
public DateTime Date { get; set; }
}
Сокращение здесь очевидно оптимально. Тем не менее, я не уверен, есть ли встроенный способ перегрузить setter для приема нескольких типов. Я понимаю, что могу создать отдельный публичный метод для установки значения, но это принесет жертву возможность использовать инициализаторы объектов.
Есть ли способ напрямую перегрузить setter в общедоступных свойствах для С#? Или это просто ограничение языка, и это невозможно?
Ответы
Ответ 1
Все остальные ответы правильные... но , если вы настаиваете, вы можете сделать это несколькими способами:
-
Используйте второе свойство только с установщиком:
public string DateText { set { Date = ParseDateString(value); } }
Избегайте, если это возможно, это только добавляет путаницу: -)
-
Используйте методы вместо свойств (как и в Java). Методы могут быть перегружены. Это должно быть наиболее рекомендуемым способом.
-
Используйте собственный класс (вместо DateTime
) и укажите неявные преобразования между DateTime
, string
и вашим классом. Не рекомендуется, если вы не собираетесь использовать это везде.
-
Измените свойство на object
и укажите свои преобразования в сеттере: не делайте этого
Ответ 2
Хорошо, вы сравниваете яблоки с бананами. Что у вас на Java здесь:
public void setDate(Date date) {
this.date = date;
}
public void setDate(String date) {
this.date = parseDateString(date);
}
Будет выглядеть так на С#:
public void SetDate(Date date)
{
this.date = date;
}
public void SetDate(String date)
{
this.date = ParseDateString(date);
}
Единственное отличие: имена элементов PascalCase
и расположение скобки открытия области.
В вашем коде Java есть перегруженные методы; вышеуказанный С# имеет перегруженные методы.
AFAIK вы не можете перегружать средство настройки свойств, потому что:
public DateTime Date
{
get { return this.date; }
set { this.date = value; }
}
... тип value
определяется типом элемента, здесь DateTime
.
Итак, если вы хотите перегрузки метода, методы перегрузки, а не свойства. Помните, что свойства С# - это просто синтаксический сахар для методов getter и setter.
Ответ 3
Авто свойства не поддерживают это. Таким образом, вам придется делать то же, что и на Java.
Конечно, вы также можете их смешивать: предоставить свойство auto и дополнительные методы set, чтобы установить свойство с использованием разных типов.
public class MyObject
{
public DateTime Date { get; set; }
public void SetDate(string date)
{
this.Date = DateTime.Parse(date);
}
}
Ответ 4
Я собираюсь написать другой ответ и утверждать, что
public void setDate(Date date) {
this.date = date;
}
public void setDate(String date) {
this.date = parseDateString(date);
}
- это плохая практика для начала.
Выполняя вышеуказанное, вы утверждаете, что обе строки и даты являются допустимыми значениями для Date
. Это не так - то, что вы действительно хотите, это Date
. Если пользователь имеет строку и хочет, чтобы он преобразовал Date
, они должны полагаться на функциональность синтаксического разбора в API Date
(DateFormat.parse()
в Java, DateTime.Parse()
на С#), а не на ваш API.
Если Date
- это класс, определенный вами, и вы действительно хотите, чтобы Date
и string
были взаимозаменяемы, вы должны использовать неявные разговоры в класс Date
, не запрашивая пользователей вашего класса Date
для записи перегрузок.