Аксессуар с различными наборами и типами?
Простой вопрос, надеюсь, простой ответ:
Я хотел бы сделать следующее:
private DateTime m_internalDateTime;
public var DateTimeProperty
{
get { return m_internalDateTime.ToString(); } // Return a string
set { m_internalDateTime = value; } // here value is of type DateTime
}
Вышеприведенное является лишь примером того, что я пытаюсь сделать. Я хотел бы иметь открытый аксессор к внутренней переменной типа x. Я хочу получить эту переменную как строку, но установить ее с помощью чего-то типа x.
Возможно ли это?
- редактировать -
Я просто понял, что могу сделать что-то вроде:
private DateTime m_internalDateTime;
public object DateTimeProperty
{
get { return m_internalDateTime.ToString(); } // Return a string
set { m_internalDateTime = (DateTime)value; } // here value is of type DateTime
}
Но тогда, допустим, я использую тип y вместо "string" как мой тип get. Если я хочу использовать "DateTimeProperty" еще там, где в моем коде, мне придется его бросить.
Ответы
Ответ 1
Нет. Вы можете, очевидно, добавить .ToString() в вызывающий код, но вы не можете делать то, что вы предлагаете, без разных имен:
private DateTime m_internalDateTime;
public DateTime SetDateTime { set { m_internalDateTime = value; } }
public string GetDateTime { get { return m_internalDateTime.ToString(); } }
Или даже лучше использовать методы вместо свойств (как отмечено в комментариях):
private DateTime m_internalDateTime;
public void SetDateTime(DateTime dateTime) { m_internalDateTime = dateTime; }
public string GetDateTime() { return m_internalDateTime.ToString(); }
Имейте в виду, что var
используется для неявных переменных, а не динамических переменных типа компиляции.
Определенно не делайте то, что вы отметили в своем редактировании. Он ввел разрыв в конвенции, возможные последствия для производительности (хотя и незначительные) и значительные проблемы с локализацией.
Ответ 2
Как свойство, это невозможно. Вы можете сделать методы Get и Set, которые имеют разные типы, но для свойства типы должны быть одинаковыми.
EDIT:
В то время как:
private DateTime m_internalDateTime;
public object DateTimeProperty
{
get { return m_internalDateTime.ToString(); } // Return a string
set { m_internalDateTime = (DateTime)value; } // here value is of type DateTime
}
является синтаксически правильным, будет компилироваться и позволяет принимать DateTime в качестве входных данных и возвращать строку, это не будет хорошим планом. Он работает, но он заставляет вас и всех, обращающихся к этому коду, выполнять ненужную проверку. Кроме того, он уязвим для другого разработчика в будущем, не зная или не понимая неявных правил, для которых вы потеряли безопасность времени компиляции. Кроме того, его вряд ли больше код для создания двух свойств или двух методов, которые выполняют одну и ту же цель, строго типизированным образом.
Лично я бы рекомендовал использовать два метода (см. комментарий Джеффа Йетса для объяснения причин).
private DateTime m_internalDateTime;
public string GetDateTime()
{
return m_internalDateTime.ToString();
}
public void SetDateTime(DateTime dateTime)
{
m_internalDateTime = dateTime;
}
Ответ 3
Не так, но вы можете иметь второе свойство, которое обращается к полю m_internalDateTime.
public string DateTimeString
{
get { return m_internalDateTime.ToString(); }
}
Ответ 4
Может быть, это помогает
public class TDecimal
{
private decimal? m_value;
public bool HasValue { get { return m_value.HasValue; } }
public decimal Value { get { return m_value.Value; } }
public static implicit operator TDecimal(string a_value)
{
decimal d;
if (decimal.TryParse(a_value, out d))
{
return new TDecimal() {m_value = d};
}
return new TDecimal() {m_value = null};
}
public static implicit operator decimal(TDecimal a_value)
{
if(a_value.HasValue)
{
return a_value.Value;
}
throw new ArgumentNullException("a_value");
}
}
public class A
{
public TDecimal Prop { get; set; }
}
A a = new A();
a.Prop = "123";
if (a.Prop.HasValue)
{
decimal d = a.Prop;
}
Ответ 5
Простой ответ "нет", на ваш внешний код ваше свойство будет вести себя точно так, как это было бы с полем, вы не можете иметь свойство, имеющее разные типы set/get, так же, как вы не могли бы установить подачу с типом и когда вы запрашиваете его, получите другой тип.
Ответ 6
как насчет:
private DateTime intDT;
public string DateTimeProperty
{
get { return intDT.ToString(); } // Return a string
set
{
DateTime dt;
if (DateTime.TryParse(value, out dt))
intDT = dt;
else throw new ArgumentException(string.Format(
"{0} cannot be converted to a DateTime.", value);
}
}