Is it possible to set a class variable using a different variable type [closed]

≡放荡痞女 提交于 2019-12-25 01:55:14

问题


is it possible to set a c# variable with a different variable type value than what the variable one is setting?

public class Test{

   public DateTime TimeSinceEpoch {
      get {return TimeSinceEpoch; }
      set{ 
         DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
         TimeSinceEpoch = Epoch.AddMilliseconds(value);}} //<-the value that's expected is a DateTime value..
}

How can i write: 'TimeSinceEpoch = 1549090800000' and use TimeSinceEpoch as a normal DateTime variable?

Without Having tow sepperate get and set variables inside the class


回答1:


This isn't allowed even in C++/CLI which does have a syntax for it:

public ref struct Test
{
    property System::DateTime TimeSinceEpoch
    {
        DateTime get();
        void set(DateTime);
        void set(long long);
    }
};

You get the following error:

error C3902: 'set': type of last parameter must be 'System::DateTime'

Intellisense actually produces two complaints, depending on which order you write them:

E1930: a 'set' accessor was already declared for this property at

or

E1942: the last parameter of the 'set' accessor does not match the property type

The underlying problem is that a .NET property has to list a type and a maximum of one setter in the metadata (Have a look at PropertyInfo.GetSetMethod -- it returns one setter or null, not an array). Even though you could easily overload the setter function itself:

void set_TimeSinceEpoch(DateTime)
void set_TimeSinceEpoch(long)

only one of these two functions could be associated to the property.

You could use a helper type to allow multiple incoming types:

struct SuperDateTime
{
    public DateTime Value;
    public static implicit operator SuperDateTime(DateTime d) { return new SuperDateTime { Value = d }; }
    public static implicit operator SuperDateTime(long x) { return new SuperDateTime { Value = Epoch.AddMilliseconds(x) }; }
    public static implicit operator DateTime(SuperDateTime d) { return d.Value; }
}

but this will break readers of the property, who now have to say TimeSinceEpoch.Value before using a member (if passing as an argument to another function, the implicit conversion will kick in). To overcome that, you'd need to write a forwarding function for every single member DateTime has.




回答2:


You need a private variable for DateTime and a long property. See code below :

    public class Test
    {

       private DateTime Epoch { get;set; }
       public long TimeSinceEpoch {
          get {return  Epoch.Ticks; }
          set{ 
             DateTime temp = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
             Epoch = temp.AddMilliseconds(value);
          } 
        }
    }



回答3:


You may just use it the way you do and to get Milliseconds:

var ms = (TimeSinceEpoch - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliSeconds;

or maybe create an extension method for it like:

public static class Extensions
{
     public static long MilliSeccondsSinceEpoch(this DateTime d)
     {
         DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
         return (d - Epoch).TotalMillisecond;
     }
}

Then you can use it like:

TimeSinceEpoch = DateTime.Now;
var ms = TimeSinceEpoch.MilliSeccondsSinceEpoch();



回答4:


The following code works as i wanted it to. Hope it helps somone else

public class Test{
   private DateTime Time {get;set;}
   public object TimeSinceEpoch {
      get{
         return (DateTime)Time
      }
      set{
         DateTime x = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
         Time = x.AddMilliseconds(Convert.ToDouble(value));
      }
   }
}



回答5:


You could achieve this using implicit casts:

public struct EpochBasedDateTime
{
    public EpochBasedDateTime(DateTime value) => Value = value;
    public EpochBasedDateTime(int milliseconds)
        : this(Epoch.addMilliseconds(milliseconds)
    {
    }

    public static readonly DateTime Epoch = new DateTime(1970,1,1);
    public DateTime Value {get;}
    public static implicit operator EpochBasedDateTime (int milliseconds)
       => new EpochBasedDateTime(milliseconds);
    public static implicit operator DateTime (EpochBasedDateTime date)
       => date.Value;
}

So you can

public class Test
{
    public EpochBasedDateTime TimeSinceEpoch {get; set;}
}

var test = new Test();
test.TimeSinceEpoch =  12345;
DateTime dt = test.TimeSinceEpoch;

However, you're probably better off explicitly converting your number to a date using a utility method:

public static class Epoch
{
    public static readonly DateTime Value {get;} = new DateTime(1970,1,1);
    public static DateTime AddMilliseconds(ms)
        => Value.AddMilliseconds(ms);            
}

So you can

DateTime foo = Epoch.AddMilliseconds(12345);

or

DateTime foo = Epoch.Value.AddMilliseconds(12345);


来源:https://stackoverflow.com/questions/55318827/is-it-possible-to-set-a-class-variable-using-a-different-variable-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!