问题
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