I'm implementing a system to send Messages between different parts of a program I'm writing. There are some generic message types as well as some specific to each part of the program. I would like to avoid the hierarchy rot inherent in deriving from a base message class for each type, So i'm encapsulating this type in an int or ushort. Then, I centralize the different types with a "Messages" namespace, and a static class with a bunch of constants. However, I ran into the issue of having to maintain a list of unique numbers for each different section:
namespace Messages
{
public static class Generic
{
public const Int32 Unknown = 0;
public const Int32 Initialize = 1;
...
public const Int32 Destroy = 10;
}
}
Then elsewhere
namespace Messages
{
public static class Graphics
{
public const Int32 Unknown = 0;
public const Int32 AddGraphic = 11; // <-- ?
}
}
Having that arbitrary 11 seems difficult, especially if I have several of these, maintaining and updating to make sure there are no collisions seems to be a pain. Is there an easy solution in order to make sure each reference to this is unique? I tried using static readonly, initializing them off of a Unique.ID() function in a static constructor, but if I do that I am unable to switch() over the passed Message type, as it says "A constant type is expected" for each case.
Is there some reason you aren't using enums?
public enum MessageTypes
{
Unknown,
Initialize,
...
}
-- Edit:
Elaborating on my comment, Consider
enum MessageType
{
Update,
Delete,
Destroy
}
MessageType t = ...;
switch(t){
case MessageType.Update:
DoUpdate();
}
}
Versus:
interface IActionable
{
void Do ();
}
public abstract class ActionableBase : IActionable
{
// some other things
public abstract void Do ();
}
public class UpdateAction : ActionableBase
{
public override void Do ()
{
// Update Code
}
}
...
IActionable a = ...;
a.Do();
You can use a number range for each class. Define a base number for the class and add 0, 1, 2, etc to that base number.
If you want to keep them numeric one way is to divide them into different magnitudes:
namespace Messages
{
public static class Generic
{
// these messages are 3-figure numbers
public const Int32 Unknown = 0;
public const Int32 Initialize = 101;
...
public const Int32 Destroy = 110;
}
public static class Graphics
{
// these messages are 4-figure numbers
public const Int32 Unknown = 0;
public const Int32 AddGraphic = 1001; // <-- ?
// and so on...
}
}
Then you just need to make sure that you keep within the boundaries for each type of message.
This isn't automatic, but it may be a bit easier to maintain then copying the values everywhere:
public enum Generic
{
Unknown = 0,
Initialize = 1,
Destroy = 10
}
public enum Graphics
{
AddGraphic = Generic.Destroy + 1
}
So, you can have all of your specific enums start with the value from a previous enum set and build them up like that.
In your actual objects, you could store them as int's and just convert whatever enum value to the appropriate int.
Although, it seems that inheritance may be inevitable in this case since there is a natural hierarchy in your data model.
I suggest you lookup the difference between 'command' & 'message', this might help you come to the conclusion that the use of magic numbers\enums inside messages is a bad idea.
Ideally you want to create 'commands' that are observed and actioned by listeners...
HTH
Ollie
If you really, really want to do this, you can create one generic private Enum that holds all of the possible values.
You can then expose those values through your separate classes as read-only properties that expose the enums as Int32s - e.g.
namespace Messages
{
private enum AllMessageTypes
{
Update,
Delete,
Destroy,
AddGraphic
}
public static class Generic
{
public Int32 Update
{
get { return (Int32)AllMessageTypes.Update; }
}
...
}
public static class Graphics
{
public Int32 AddGraphic
{
get { return (Int32)AllMessageTypes.AddGraphic ; }
}
}
}
However - I'd recommend you redesign your solution. This seems to be asking for trouble (as I'm sure people will comment on)
Related
My problem, narrowed down to a simple explaination, is the following:
I have a class which needs to work with a number (without changing it) which is subject to change. This number doesn't necessarily come from another class, and it can be anything.
But I'd like to only "give" it to the class once, instead of constantly having to call update methods or having to create a wrapper (since again, as I said, this should work with any kind of number and having to wrap up everything is kind of unpratical).
Here's some code, hoping it helps:
public class SimpleExample
{
int value;
public SimpleExample(int variableOfWhichINeedAReference)
{
//Of course this won't work, but I'll keep it simple.
value = variableOfWhichINeedAReference;
}
public void DisplayValue()
{
print(value);
}
}
public class RandomClass
{
int myValue = 10;
SimpleExample s = new SimpleExample(myValue);
public void WorkWithValue()
{
myValue++;
}
public void Display()
{
print(foo);
print(bar);
s.DisplayValue();
}
}
Now, the problem seems pretty obvious: If I instantiate a SimpleExample and give it a variable as a parameter, it will get its value rather than a reference to it.
Is there a simple enough way that can avoid me the creation of a wrapper? Thanks.
Make a really simple class:
class Ref<T>
{
public T Value;
public Ref<T>()
{
}
public Ref<T>(T value)
{
this.Value = value;
}
}
Then use it like this:
class A
{
Ref<int> x;
public A(Ref<int> x)
{
this.x = x;
}
public void Increment()
{
x.Value++;
}
}
...
Ref<int> x = new Ref<int>(7);
A a = new A(x);
a.Increment();
Debug.Assert(x.Value == 8);
Note that the Ref<T> class here is a reference to a value - not a reference to a variable. If you want a reference to a variable, use Eric Lippert's solution (as pointed out by Filip).
So what you want is not an int, but rather a way of getting an int at some point in time. There are several ways of doing this, one of which is to have your object accept a Func<int>. Then the code can pass in a method that returns the current value of...whatever, rather than the value at the time SimpleExample is created. Using a lambda to close over a variable makes doing this much easier as well.
public class SimpleExample
{
Func<int> func;
public SimpleExample(Func<int> func)
{
this.func = func;
}
public void DisplayValue()
{
print(func());
}
}
public class RandomClass
{
int myValue = 10;
SimpleExample s;
public RandomClass()
{
s = new SimpleExample(() => myValue);
}
public void WorkWithValue()
{
myValue++;
}
public void Display()
{
print(foo);
print(bar);
s.DisplayValue();
}
}
There is no standard wrapper for the purpose you seek, though a single-element array could be used for that purpose. Alternatively, one could define a simple wrapper type:
public class ExposedValueHolder<T> { public T Value; } // Really simple class, eh?
and then use an ExposedValueHolder<YourStructType> to wrap your object. It's not possible in general to capture something passed as an arbitrary ref parameter, since objects may live indefinitely but byrefs (the things which are actually passed when using ref parameters) may die any time after function they're passed to goes out of scope.
I'm currently writing a class to calculate the average download speed over a defined period of time, taking a defined number of samples. The way I thought this would work is that this class runs a Timer object, which calls a method inside said class that will look at the bytes downloaded (maintained in a parent class, the FTPDownloadFile), and then store that sample in a Queue. My issue is accessing the number of bytes downloaded, however.
My method of accessing that information was through a reference that was passed in when the download calculating class was constructed, however, it seems like I'm not understanding/using references correctly. The variable that is passed in always appears to be 0, even though I can see the original variable changing.
Can anyone tell me what I'm doing wrong / suggest a better way for me to accomplish what I want to do?
First, here is the class that is handling the calculation of the download speed:
public class SpeedCalculator
{
private const int samples = 5;
private const int sampleRate = 1000; //In milliseconds
private int bytesDownloadedSinceLastQuery;
private System.Threading.Timer queryTimer;
private Queue<int> byteDeltas = new Queue<int>(samples);
private int _bytesDownloaded;
public SpeedCalculator(ref int bytesDownloaded)
{
_bytesDownloaded = bytesDownloaded;
}
public void StartPolling()
{
queryTimer = new System.Threading.Timer(this.QueryByteDelta, null, 0, sampleRate);
}
private void QueryByteDelta(object data)
{
if (byteDeltas.Count == samples)
{
byteDeltas.Dequeue();
}
byteDeltas.Enqueue(_bytesDownloaded - bytesDownloadedSinceLastQuery);
bytesDownloadedSinceLastQuery = _bytesDownloaded;
}
/// <summary>
/// Calculates the average download speed over a predefined sample size.
/// </summary>
/// <returns>The average speed in bytes per second.</returns>
public float GetDownloadSpeed()
{
float speed;
try
{
speed = (float)byteDeltas.Average() / ((float)sampleRate / 1000f);
}
catch {speed = 0f;}
return speed;
}
That class is contained inside of my FTPDownloadFile class:
class FTPDownloadFile : IDisposable
{
private const int recvBufferSize = 2048;
public int bytesDownloaded;
public SpeedCalculator Speed;
private FileStream localFileStream;
FtpWebResponse ftpResponse;
Stream ftpStream;
FtpWebRequest ftpRequest;
public List<string> log = new List<string>();
private FileInfo destFile;
public event EventHandler ConnectionEstablished;
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator(ref bytesDownloaded);
}
public void GetFile(string host, string remoteFile, string user, string pass, string localFile)
{
//Some code to start the download...
Speed.StartPolling();
}
public class SpeedCalculator {...}
}
This is a common 'issue' with understanding 'ref' parameters in C#. You see, unlike C+, there are no real value references in C#.
In C++, when you pass-by-reference, you actually internally pass pointer to the variable. Therefore, you can have a class member variable of type "int&" that is actual reference to an integer stored elsewhere.
In C#, 'ref' or 'out' parameter works in a similar way, but noone talks about pointers. You cannot store the reference. You cannot have a 'ref' class member. Look at your class: the sotrage variable is of type 'int', plain 'int', not a reference.
You actually are passing that value by-ref, but then you copy it to the member variable. The 'reference' is gone at the point where your constructor ends.
To walk it around, you have to keep the actual source object, and either introduce a strong dependency, or a weak one by an interface, or do it lazy/functional way - by a delegate
Ex#1: strong reference
public class SpeedCalculator
{
private const int samples = 5;
private const int sampleRate = 1000; //In milliseconds
private int bytesDownloadedSinceLastQuery;
private System.Threading.Timer queryTimer;
private Queue<int> byteDeltas = new Queue<int>(samples);
private FTPDownloadFile downloader; // CHANGE
public SpeedCalculator(FTPDownloadFile fileDownloader) // CHANGE
{
downloader = fileDownloader;
}
public void StartPolling()
{
queryTimer = new System.Threading.Timer(this.QueryByteDelta, null, 0, sampleRate);
}
private void QueryByteDelta(object data)
{
if (byteDeltas.Count == samples)
{
byteDeltas.Dequeue();
}
byteDeltas.Enqueue(_bytesDownloaded - bytesDownloadedSinceLastQuery);
bytesDownloadedSinceLastQuery = downloader.bytesDownloaded; // CHANGE
}
//and in the other file
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( this ); // CHANGE
}
In C#, every object (class MyObject) is passed by reference, or implicit pointer, therefore taking FTPDownloadFile by parameter and assigning it to a member variable does not copy it, it is truly passed by ref (on the other hand, values (int, decimal, ..) and structs (struct MyThing) are always passed by value, so your original _bytes = bytes made a copy of int). Hence, later, I can just query the
Ex#2: "weak" reference
public interface IByteCountSource
{
int BytesDownloaded {get;}
}
public class FTPDownloadFile : IDisposable, IByteCountSource
{
.....
public int BytesDownloaded { get { return bytesDownloaded; } }
.....
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( this ); // note no change versus Ex#1 !
}
}
public class SpeedCalculator
{
....
private IByteCountSource bts;
public SpeedCalculator(IByteCountSource countSource) // no "FTP" information!
{
this.bts = countSource;
}
...
private void QueryByteDelta(object data)
{
....
bytesDownloadedSinceLastQuery = bts.BytesDownloaded;
}
The first example was quick and dirty. In general, we usually want the classes to know as least as possible about all other. So why should the SpeedCalculator know about the FTPDownloadFile? All it needs to know is the current byte-count. So I introduced an interface to 'hide' the actual source behind. Now the SpeedCalculator can take the value from any object that implements the interface - be it FTPDownloadFile, HTTPDownloadFile or some DummyTestDownloader
Ex#3: delegates, anonymous functions, etc
public class SpeedCalculator
{
....
private Func<int> bts;
public SpeedCalculator(Func<int> countSource)
{
this.bts = countSource;
}
...
private void QueryByteDelta(object data)
{
....
bytesDownloadedSinceLastQuery = bts();
}
// and in the other file
private int getbytes() { return bytesDownloaded; }
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( this.getbytes ); // note it is NOT a getbytes() !
}
// or even
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( () => this.bytesDownloaded ); // CHANGE
}
The example with an interface is pretty, but the interface was 'small'. One is ok, but sometimes you'd need to introduce dozens of such one-property or one-method interfaces, it gets somewhat boring and cluttering. Especially if all of that is 'internal implementation' that anyways isn't published for any other people to use. You can very easily drop such small interface with a short lambda, as in the third example. Instead of receiving and storing a object-that-implememts-an-interface, I changed the parameter to Func. This way I require to get "a method that returns an INT". Them, I pass the some method. Note that during new SpeedCalculator, I do not call the this.getbytes(), I pass the method without parenthesis - this causes the method to be wrapped into Func delegate, that will be later invoked as bts(), and will return current counter. This getbytes is rarely used, only in this one place - so I can even drop it completely and write anonymous function right at the point of constructor call, as you can see in the "or even" part.
However, I'd suggest you to stick with interfaces for now, they are much clearer to read and understand.
Given a Queue<MyMessage>, where MyMessage is the base class for some types of messages: all message types have different fields, so they will use a different amount of bytes. Therefore it would make sense to measure the fill level of this queue in terms of bytes rather than of elements present in the queue.
In fact, since this queue is associated with a connection, I could better control the message flow, reducing the traffic if the queue is nearly full.
In order to get this target, I thought to wrap a simple Queue with a custom class MyQueue.
public class MyQueue
{
private Queue<MyMessage> _outputQueue;
private Int32 _byteCapacity;
private Int32 _currentSize; // number of used bytes
public MyQueue(int byteCapacity)
{
this._outputQueue = new Queue<MyMessage>();
this._byteCapacity = byteCapacity;
this._currentSize = 0;
}
public void Enqueue(MyMessage msg)
{
this._outputQueue.Enqueue(msg);
this._currentSize += Marshal.SizeOf(msg.GetType());
}
public MyMessage Dequeue()
{
MyMessage result = this._outputQueue.Dequeue();
this._currentSize -= Marshal.SizeOf(result.GetType());
return result;
}
}
The problem is that this is not good for classes, because Marshal.SizeOf throws an ArgumentException exception.
Is it possible to calculate in some way the size of an object (instance of a class)?
Are there some alternatives to monitor the fill level of a queue in terms of bytes?
Are there any queues that can be managed in this way?
UPDATE: As an alternative solution I could add a method int SizeBytes() on each message type, but this solution seems a little ugly, although it would perhaps be the most efficient since You cannot easily measure a reference type.
public interface MyMessage
{
Guid Identifier
{
get;
set;
}
int SizeBytes();
}
The classes that implement this interface must, in addition to implementing the SizeBytes() method, also implement an Identifier property.
public class ExampleMessage
{
public Guid Identifier { get; set; } // so I have a field and its Identifier property
public String Request { get; set; }
public int SizeBytes()
{
return (Marshal.SizeOf(Identifier)); // return 16
}
}
The sizeof operator can not be used with Guid because it does not have a predefined size, so I use Marshal.SizeOf(). But at this point perhaps I should use the experimentally determined values: for example, since Marshal.SizeOf() returns 16 for a Guid and since a string consists of N char, then the SizeBytes() method could be as following:
public int SizeBytes()
{
return (16 + Request.Length * sizeof(char));
}
If you could edit the MyMessage base class with a virtual method SizeOf(), then you could have the message classes use the c# sizeof operator on its primitive types. If you can do that, the rest of your code is gold.
You can get an indication of the size of your objects by measuring the length of their binary serialization. Note that this figure will typically be higher than you expect, since .NET may also include metadata in the serialized representation. This approach would also require all your classes to be marked with the [Serializable] attribute.
public static long GetSerializedSize(object root)
{
using (var memoryStream = new MemoryStream())
{
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, root);
return memoryStream.Length;
}
}
Is there an equivalent of this in C# for static members?
I like to use this to make my code more readable, but wondered if there was an equivalent for static members.
I suppose if you use this. to reinforce that you are referring to instance members, the equivalent in a static member would be to use ClassName.
But stylistically, why add code that doesn't change meaning?
edit to add various clarifications:
My last sentence above can be illustrated with these examples:
class Example1
{
public int J { get; set; }
public Example1()
{
J = 0;
}
// These two methods have *exactly* the same CIL
public int InstanceMethodLong()
{
return this.J;
}
public int InstanceMethodShort()
{
return J;
}
}
The this. in InstanceMethodLong does not change the meaning as compared with InstanceMethodShort.
Statically:
class Example2
{
public static int K { get; set; }
static Example2()
{
K = 0;
}
// These two methods have *exactly* the same CIL
public int StaticMethodLong()
{
return Example2.K;
}
public int StaticMethodShort()
{
return K;
}
The Example2. in StaticMethodLong does not change the meaning as compared with StaticMethodShort.
In both these cases, adding the qualifier results in the same CIL, the same behaviour, and is more source to write, read, and understand. Stylistically - and I will happily accept that this is a question of code style - I see no reason for it to be there.
With underscore prefixes the situation is slightly different:
class Example3
{
int _j;
public int J
{
get { return _j; }
set
{
_j = value;
// and do something else,
// to justify not using an auto-property
}
}
public Example3()
{
J = 0;
}
public int MethodWithParameter(int j)
{
// Now there is a *difference* between
return j;
// and
return _j;
}
}
Here, in MethodWithParameter, there is a difference between referring to _j and j - so we are deliberately and explicitly expressing different meaning. It's true that the compiler doesn't care what we call our variable names, but it does care what variables we are referring to! So in the body of MethodWithParameter, using or not using an underscore isn't just stylistic, it's semantic. Which isn't the particular issue we're addressing in this question.
As a static member is not meant to belong to any particular instance (as this refers to an instance of an object, with different settings possible per instance), what you would instead want to do is use ClassName.Member instead of this.Member.
public class Orange
{
public static string Tastes = "sweet";
public static string FoodType(){
return "fruit";
}
}
Would be called by:
Console.WriteLine(Orange.Tastes);
Same goes for static methods, as well:
Console.WriteLine(Orange.FoodType()).
Please note this is a contrived example for demonstration only. :)
You may able to use the class name to reference other static properties.
Your code becomes a bit more resistant to copy/paste but that's not always a bad thing.
Unfortunately no, there is no this for static methods. To help differentiate static members from class members I prefix it with the class name.
class Test {
static Regex TextRegex = new Regex(...);
public static bool TestString(string input) {
return Test.TextRegex.IsMatch(input);
}
}
I like "this" as well to realsie from the first look where the state is changing. You may want to consider type's name for static members in this case.
OK, so I have a database field of type char(1) that has a small number of possible state codes (e.g. 'F'= Failure, 'U'=Unknown, etc.). I'd like to have a C# enum class that corresponds to these states. I can do:
public enum StatusCode : byte {
Unknown = (byte) 'U',
Failure = (byte) 'F',
// etc.
}
So far so good. But in the DataTable returned from the database, the column values are System.Data.SqlTypes.SqlString instances. There are obviously some issues converting from a C# string (or even a C# char) to a C# byte (since C# char is really a UTF-16 codepoint). But in this case I know the values are constrained to a small set, and the code should throw an exception if a value outside this set comes through.
With that in mind, what's the best way of doing this? Is it safe to cast from a SqlString to a byte? Would Convert.ToByte() be better? Would it be better to simply use a switch/case construct to crosswalk the values into the enum?
I'm looking for the "best" way to do this, not only in terms of getting the right results but also for code clarity. I suppose I could also just use some constants like
public const char UnknownStatus = 'U';
public const char FailureStatus = 'F';
But I'd rather use an enum if possible. Any thoughts?
Edit: To clarify what I want do do with this, I'm expecting to use these values frequently throughout my code. For example, I want to be able to do things like:
public void DoSomething(StatusCode currentStatus) {
if(currentStatus == StatusCode.Failure) {
throw new SomeException();
}
switch(currentStatus) {
case StatusCode.Unknown:
// do something
break;
}
}
And so forth. I particularly want to avoid things like:
public void DoSomething(char currentStatus) {
if(currentStatus == 'F') {
// do something
}
}
Since in this case I'm using what amounts to "magic numbers" all over the place. In particular, this would make migrating to some other state-flagging system virtually impossible. Does that make sense?
Maybe a "constant" object?
public sealed class StatusCode {
private char value;
public static readonly StatusCode Unknown = new StatusCode('U');
public static readonly StatusCode Failure = new StatusCode('F');
private StatusCode(char v) {
value = v;
}
public override string ToString() {
return value.ToString();
}
}
Then, later in your code, you could use it like an enum: StatusCode.Unknown. You could also provide an internal method to 'parse' a received value into an object of StatusCode.
Skip to edit Have you tried this (which doesn't work as you've checked and commented):
public enum StatusCode : char
{
Failure = 'F',
Unknown = 'U',
...
}
EDIT - correct solution
or this (maybe even try with a struct):
public sealed class StatusCode
{
public static readonly char Failure = 'F';
public static readonly char Unknown = 'U';
...
public char Value { get; set; }
}
your code you provided would work like this:
public void DoSomething(StatusCode currentStatus) {
if(currentStatus.Value == StatusCode.Failure) {
throw new SomeException();
}
switch(currentStatus.Value) {
case StatusCode.Unknown:
// do something
break;
}
}
If you don't like to use Value property you can always implement implicit equality operator between StatusCode and char types. In that case, your code wouldn't change a bit.
If you're on .NET 2.0 and higher, you could implement this using a generic dictionary:
Dictionary<char,string> statusCode = new Dictionary<char,string>();
statusCode.Add('U', "Unknown");
statusCode.Add('F', "Failure");
or alternatively:
Dictionary<char,StatusCode> statusCode = new Dictionary<char,StatusCode>();
statusCode.Add('U', StatusCode.Unknown);
statusCode.Add('F', StatusCode.Failure);
and you could access the string representation for a given code like so:
string value = statusCode['A'];
or
StatusCode myCode = statusCode['A'];
and so on. You would have to fill that dictionary from the database values, or from some kind of a config file or something.
Marc
Would something like this work for you?
public Enum StatusCode : int{
[StringValue("U")]
Unknown =0,
[StringValue["F"]
Failuer=1
}
If you have a table called StatusCode which includes an integer primary key then you could use that as your identifier as well as hook it into your logic. And in that case, the enum would be the best thing to use. Though i'm not sure if this is feasible for you.
One option is to setup your enum with identical names to the values in your database, such as:
enum StatusCode
{
/// <summary>Unknown</summary>
U = 0,
/// <summary>Failure</summary>
F,
/// <summary>Etc</summary>
E
}
Then use a static method to convert char values to an enumerated value
private StatusCode CharToEnum(string statusCodeChar)
{
foreach (FieldInfo fi in typeof(StatusCode).GetFields())
{
if (fi.Name == statusCodeChar) return (StatusCode)fi.GetValue(null);
}
return StatusCode.U;
}
Short and sweet my man.. Does everything you need it to. You shouldn't need to use enum because you don't need it to assign an internal value to your possible states, you already know the values to your states.
public sealed class StatusCode
{
public const string Unknown= "U";
public const string Failure= "F";
public const string Success= "S";
}