是的,我知道在c#中没有任何虚拟的静态成员,但我有一个问题,他们会真的很有帮助,我看不到一个好的方法来继续。
我有一个标准类型的系统,在这个系统中,我通过通信通道发送数据包并得到响应。通信系统需要知道要等待多少字节的响应,并且每个命令类型的响应长度都是固定的,因此我定义了以下代码:
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())的成员函数的返回值,但它总是一个固定值。
所以这一切都很好,我可以像这样写代码:
void Communicate(IPacket packet)
{
Send(packet.DataToSend());
WaitToReceive(packet.ReceiveLength);
}而且它工作得很完美。
但现在我想输出数据包的摘要。我想要一个显示命令名(类名)和相应ReceiveLength的表。我希望能够写出这样的(伪)代码:
foreach (Class cls in myApp)
{
if (cls.Implements(IPacket))
{
Debug.WriteLine("Class " + cls.Name + " receive length " + cls.ReceiveLength);
}
}当然,ReceiveLength需要一个对象。
我不认为我可以在这里使用属性,c#不会让我说:
[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) { }
}因为自定义属性是在编译时创建的(对吗?),在调用静态构造函数之前很久。
构造每种类型的对象并不是特别令人愉快(还是伪代码):
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);
}我需要。虚拟静态属性。
发布于 2017-06-28 04:48:19
只需创建一个public static CommandX.Length属性,让它返回您现在的ReceiveLength属性,然后让ReceiveLength引用它。要想两全其美,首先你需要这两个世界。
发布于 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 */... }方法中一样。这样,您就可以将所有实体的大小方面封装到一个单独的类中。
https://stackoverflow.com/questions/44789482
复制相似问题