Аксессуар с различными наборами и типами?

Простой вопрос, надеюсь, простой ответ:

Я хотел бы сделать следующее:

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);           
      } 
}