1

I'm developing some kind of TCP-server and have concluded one nasty thing.

Here is a piece of code:

public void GetSessionId(byte[] secretPhrase)
{
    var message = new ZllnpMessage
    {
        Head = CreateHeader(Session.Opcodes.GetSessionToken),
        Body = CreateBodyContent(secretPhrase)
    };

    message.CalculateHash(saveHash: true);

    var data = message.ToBinary();
    socket.Send(data);
    socket.Receive();
}

Here you can see the line:

message.CalculateHash(saveHash: true);

It's required to calculate control sum for each message.

There is a simple solution: just pass head & body to constructor and then calcuate inside ZllnpMessage.

OK, that's an option, but what if I would like to do the next:

Initialize object both with properties and provide it something like that:

var message = new ZllnpMessage(saveHash: true)
{
    Head = CreateHeader(Session.Opcodes.GetSessionToken),
    Body = CreateBodyContent(secretPhrase)
};

Then later, spy for the (maybe using events with Lazy) property value changes to implement later autocall.

So, I'm rather confusing what is better way to do? Can you give me a piece of advice, please?

Please, don't ask me about:

  • why TCP?
  • why not TPL with Task?

Answers:

  • TCP, because of project requirements
  • Not TPL, because I'm using old threading model with manual control, semaphores etc (I know, that it's hard and etc...)

PS

Also, question is about late method call from constructor :) Not the project design

  • 2
    It's really unclear what exactly you're asking. If you want to call `CalculateHash()` on property changes, then you'll have to implement `INotifyPropertyChanged` or roll your own, and call `CalculateHash` in each property's setter. Alternatively you can call `CalculateHash` first thing in `ToBinary()`, but all of that entirely depends on your use case and which approach **you** want to take. We don't know that, so we can't answer that. Also, "late method call from constructor" does not clarify what exactly you want to do, please elaborate. – CodeCaster Mar 01 '16 at 12:31
  • @CodeCaster I'm asking about the providing a boolean value to constructor, if it's true, then I would like to run some kind of lazy evaluation to control the changes of any properties with some kind of callback method. That callback method will check the availability to calculate the hash sum. –  Mar 01 '16 at 12:33
  • @JamesThorpe also an option :) but I want more interesting solution with using lazy evaluations –  Mar 01 '16 at 12:34

1 Answers1

3

It looks like your question is "How can I control hash calculation by passing a value to the constructor". If you want automatic hash calculation in property setters, which you optionally can switch off, you'll have to implement it anyway.

You can do so as such:

public class ZllnpMessage
{
    private bool _autoHash;

    private string _head;
    public string Head 
    { 
        get { return _head; } 
        set 
        {
            _head = value;
            if (_autoHash)
            {
                CalculateHash();
            }
        } 
    }

    public ZllnpMessage(bool autoHash)
    {
        _autoHash = autoHash;
    }

    public byte[] CalculateHash()
    {
        // return hash
    }

    public byte[] ToBinary()
    {
        // return serialized message
    }
}

However, the most straightforward way to do hash calculation is only before serialization, so in ToBinary():

public class ZllnpMessage
{
    public string Head { get; set; }

    public byte[] CalculateHash()
    {
        // return hash
    }

    public byte[] ToBinary()
    {
        CalculateHash();
        // return serialized message
    }
}
CodeCaster
  • 147,647
  • 23
  • 218
  • 272