C# 是否可以使用不同的变量类型设置类变量
是否可以设置一个c#变量,该变量的变量类型值与当前设置的变量类型值不同C# 是否可以使用不同的变量类型设置类变量,c#,class,C#,Class,是否可以设置一个c#变量,该变量的变量类型值与当前设置的变量类型值不同 公共类测试{ 公共日期时间{ 获取{return timesincepoch;} 集合{ DateTime Epoch=新的DateTime(1970,1,1,0,0,0,0,DateTimeKind.Utc); timesincepoch=Epoch.addmillizes(value);}}}/您需要DateTime的私有变量和long属性。请参阅下面的代码: public class Test {
公共类测试{
公共日期时间{
获取{return timesincepoch;}
集合{
DateTime Epoch=新的DateTime(1970,1,1,0,0,0,0,DateTimeKind.Utc);
timesincepoch=Epoch.addmillizes(value);}}}/您需要DateTime的私有变量和long属性。请参阅下面的代码:
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);
}
}
}
您可以按您的方式使用它,并获得毫秒数:
var ms = (TimeSinceEpoch - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliSeconds;
或者为其创建一个扩展方法,如:
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;
}
}
然后你可以像这样使用它:
TimeSinceEpoch = DateTime.Now;
var ms = TimeSinceEpoch.MilliSeccondsSinceEpoch();
这是不允许的,即使在C++/CLI中也有语法:
public ref struct Test
{
property System::DateTime TimeSinceEpoch
{
DateTime get();
void set(DateTime);
void set(long long);
}
};
您将得到以下错误:
错误C3902:“集”:最后一个参数的类型必须为“System::DateTime”
Intellisense实际上会产生两个投诉,具体取决于您编写投诉的顺序:
E1930:已在声明此属性的“set”访问器
或
E1942:“set”访问器的最后一个参数与属性类型不匹配
潜在的问题是.NET属性必须在元数据中列出一个类型和最多一个setter(请查看--它返回一个setter或null
,而不是数组)。即使您可以轻松地重载setter函数本身:
void set_TimeSinceEpoch(DateTime)
void set_TimeSinceEpoch(long)
这两个函数中只能有一个与属性关联
您可以使用帮助器类型来允许多个传入类型:
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; }
}
但这将破坏属性的读者,他们现在必须在使用成员之前说出timesincepoch.Value
(如果将参数传递给另一个函数,则隐式转换将开始)。要克服这一点,您需要为每个成员编写一个转发函数。以下代码按照我的要求运行。希望对其他人有所帮助
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));
}
}
}
您可以使用隐式强制转换来实现这一点:
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;
}
所以你可以
public class Test
{
public EpochBasedDateTime TimeSinceEpoch {get; set;}
}
var test = new Test();
test.TimeSinceEpoch = 12345;
DateTime dt = test.TimeSinceEpoch;
DateTime foo = Epoch.AddMilliseconds(12345);
但是,您最好使用实用方法将数字显式转换为日期:
public static class Epoch
{
public static readonly DateTime Value {get;} = new DateTime(1970,1,1);
public static DateTime AddMilliseconds(ms)
=> Value.AddMilliseconds(ms);
}
所以你可以
public class Test
{
public EpochBasedDateTime TimeSinceEpoch {get; set;}
}
var test = new Test();
test.TimeSinceEpoch = 12345;
DateTime dt = test.TimeSinceEpoch;
DateTime foo = Epoch.AddMilliseconds(12345);
或
您想设置什么timesincepoch
?请注意,您当前的代码具有无限递归。这本身不会阻止编译,但没有支持变量,只是对同一属性的循环引用。为什么不创建另一个类方法,例如setTimesincepoch(长毫秒)这就是您要查找的赋值。除非您使用相同的类型,否则不要将=用于直接赋值。此处介绍了隐式转换:可以使用操作符Implicit
创建隐式转换,但您不是DateTime
或long
的作者,因此该方法在此处不起作用。隐式转换是不需要进行显式转换(转换)的转换。(例如:int a=5;float b=a;
整数a可以隐式转换为float,而无需写入float b=(float)a;
)这会使“并将TimeSinceEpoch
用作正常的DateTime
”失败问题中说明的目标。该代码只是一个示例,需要一些小的调整。我刚刚发布了缺少的私有变量。我知道发布的代码无法正确地将unix时间转换为windows时间。这会导致“并将TimeSinceEpoch用作普通日期时间”失败问题中说明的目标,因为任何读取该属性的人都必须应用强制转换。您的编辑完全没有做任何操作。@BenVoigt:新代码使用一个变量(Time)和一个属性(timesincepoch)原始代码只有一个属性。@jdweng:本质上的改变是使属性类型System.Object
。添加字段修复了无限递归,但没有以任何方式解决问题的要点。请仔细查看解决方案和原始代码。