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 {

是否可以设置一个c#变量,该变量的变量类型值与当前设置的变量类型值不同

公共类测试{
公共日期时间{
获取{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
。添加字段修复了无限递归,但没有以任何方式解决问题的要点。请仔细查看解决方案和原始代码。