首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c#虚拟静态成员

c#虚拟静态成员
EN

Stack Overflow用户
提问于 2017-06-28 04:42:37
回答 2查看 208关注 0票数 0

是的,我知道在c#中没有任何虚拟的静态成员,但我有一个问题,他们会真的很有帮助,我看不到一个好的方法来继续。

我有一个标准类型的系统,在这个系统中,我通过通信通道发送数据包并得到响应。通信系统需要知道要等待多少字节的响应,并且每个命令类型的响应长度都是固定的,因此我定义了以下代码:

代码语言:javascript
复制
public abstract class IPacket
{
   public abstract int ReceiveLength { get; }
   public abstract byte[] DataToSend();
}

public class Command1 : IPacket
{
   public override int ReceiveLength { get { return 3; } }
   public Command1() { }
}

public class Command2 : IPacket
{
   public override int ReceiveLength { get { return DataObject.FixedLength; } }
   public Command2(int x) { }
}

public class Command3 : IPacket
{
   static DataHelperObject Helper;
   public override int ReceiveLength { get { return Helper.DataLength(); } }
   static Command3()
   {
      Helper = new DataHelperObject();
   }
   public Command3(really long list of parameters containing many objects that are a pain to set up) { }
}

请注意,在每种情况下,ReceiveLength都是一个固定值--有时它是一个简单的常量(3),有时它是其他类的静态成员(DataObject.FixedLength),有时它是静态成员(Helper.DataLength())的成员函数的返回值,但它总是一个固定值。

所以这一切都很好,我可以像这样写代码:

代码语言:javascript
复制
void Communicate(IPacket packet)
{
   Send(packet.DataToSend());
   WaitToReceive(packet.ReceiveLength);
}

而且它工作得很完美。

但现在我想输出数据包的摘要。我想要一个显示命令名(类名)和相应ReceiveLength的表。我希望能够写出这样的(伪)代码:

代码语言:javascript
复制
foreach (Class cls in myApp)
{
   if (cls.Implements(IPacket))
   {
      Debug.WriteLine("Class " + cls.Name + " receive length " + cls.ReceiveLength);
   }
}

当然,ReceiveLength需要一个对象。

我不认为我可以在这里使用属性,c#不会让我说:

代码语言:javascript
复制
[PacketParameters(ReceiveLength=Helper.DataLength())]
public class Command3 : IPacket
{
   static DataHelperObject Helper;
   static Command3()
   {
      Helper = new DataHelperObject();
   }
   public Command3(really long list of parameters containing many objects that are a pain to set up) { }
}

因为自定义属性是在编译时创建的(对吗?),在调用静态构造函数之前很久。

构造每种类型的对象并不是特别令人愉快(还是伪代码):

代码语言:javascript
复制
foreach (Class cls in myApp)
{
   IPacket onePacket;
   if (cls is Command1)
      onePacket = new Command1();
   else if (cls is Command2)
      onePacket = new Command2(3);
   else if (cls is Command3)
   {
      Generate a bunch of objects that are a pain to create
      onePacket = new Command3(those objects);
   }
   Debug.WriteLine("Class " + cls.Name + " receive length " + onePacket.ReceiveLength);
}

我需要。虚拟静态属性。

EN

回答 2

Stack Overflow用户

发布于 2017-06-28 04:48:19

只需创建一个public static CommandX.Length属性,让它返回您现在的ReceiveLength属性,然后让ReceiveLength引用它。要想两全其美,首先你需要这两个世界。

票数 0
EN

Stack Overflow用户

发布于 2017-06-28 04:59:42

一种解决方案是抛开所有编译时安全性,简单地使用反射来访问静态属性,如下所示:http://fczaja.blogspot.ch/2008/07/accessing-static-properties-using-c.html

或者,您可以将该信息分离为"PaketSizeManager“类型,该类型只包含上述字典或一些switch-case语句,外加一些从外部访问此信息的巧妙方法,就像在public int GetSize(Type t){ .../* use dictionary or switch-case here */... }方法中一样。这样,您就可以将所有实体的大小方面封装到一个单独的类中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44789482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档