2

Right now I have this interface called IMessageConfiguration<T> that implements a property called Label (of type byte). I have a map of labels to their relative message configurations in the following structure:

Dictionary<byte, dynamic> configurationMap = new Dictionary<byte, dynamic>();

Now, although the dictionary is dynamic I am only filling it with either IMessageConfiguration<double> or IMessageConfiguration<uint>. Regardless of which type is at each dictionary entry, the entry will have the property Label because all entries will ultimately have the IMessageConfiguration<T> base type. I do however understand that the compiler will have no knowledge of this.

I am writing a routine to go through the dictionary and obtain the Label property for each of the IMessageConfiguration<T> entries. Here is my current attempt at doing this:

public IList<byte> GetLabels()
{
    IList<byte> labels = new List<byte>();

    // obtain all of the labels
    foreach (var configuration in this.configurationMap)
    {
        if (configuration.Value is IMessageConfiguration<double>)
        {
            labels.Add((configuration.Value as IMessageConfiguration<double>).Label);
        }
        else if (configuration.Value is IMessageConfiguration<uint>)
        {
            labels.Add((configuration.Value as IMessageConfiguration<uint>).Label);
        }
    }

    return labels;
}

Is there a way to more cleanly obtain all of the Label properties for each of the message configurations?

As asked in the comments, here is the full definition for the IMessageConfiguration<T> interface.

public interface IMessageConfiguration<T>
{
    string Description { get; }
    byte Label { get; }
    ushort LSB { get; }
    ushort MSB { get; }
    double Resolution { get; }
    int SignBit { get; }
    string Title { get; }
    string Units { get; }
    uint Encode(T data);
    T Decode(uint message);
}
Snoop
  • 1,046
  • 1
  • 13
  • 33
  • Providing full definition of `IMessageConfiguration` interface might help to answer. – Evk Oct 09 '17 at 12:20
  • @Evk I guess I could do that, but it's really just a container-type class that has a bunch of dummy data properties. – Snoop Oct 09 '17 at 12:21
  • 1
    My point is - if `Label` property is not related to type `T` (for example if `Label` is always `string`) - you can move it to parent interface `IMessageConfiguration` and then have `Dictionary – Evk Oct 09 '17 at 12:23
  • @Evk Yes, good point. Let me provide that interface definition, and yes label is always byte. – Snoop Oct 09 '17 at 12:24
  • @Evk Updated to include the interface definition for `IMessageConfiguration`. – Snoop Oct 09 '17 at 12:28
  • But I don't see type `T` is used anywhere there. Is it intended? – Evk Oct 09 '17 at 12:30
  • @Evk I left out two methods on-purpose, one second. Let me add them back. – Snoop Oct 09 '17 at 12:31
  • Move the generic declaration towards `T Decode(uint message)` and `uint Encode(T data)` or create 2 interfaces, where one would be the non generic `IMessageConfiguration` and the second one would be `IMessageConfiguration : IMessageConfiguration` that just implements the generic methods – Icepickle Oct 09 '17 at 12:36
  • @Icepickle That seems like a good idea. – Snoop Oct 09 '17 at 12:37
  • @Icepickle How would you name the C# (.cs) for adding the interfaces like that to my project? – Snoop Oct 09 '17 at 12:38
  • I would actually keep them in the same file :) – Icepickle Oct 09 '17 at 12:39
  • @Icepickle Okay. I also asked the same question to Evk down below, thanks. – Snoop Oct 09 '17 at 12:39

1 Answers1

1

I'd say that you should avoid dynamic whenever possible. In your case you can put all non-T related properties to parent interface:

public interface IMessageConfiguration
{
    string Description { get; }
    byte Label { get; }
    ushort LSB { get; }
    ushort MSB { get; }
    double Resolution { get; }
    int SignBit { get; }
    string Title { get; }
    string Units { get; }
}

public interface IMessageConfiguration<T> : IMessageConfiguration {
    uint Encode(T data);
    T Decode(uint message);
}

And use Dictionary<byte, IMessageConfiguration> instead. Even if you insist on using dynamic for some reason - you can do yourDict.OfType<IMessageConfiguration>().Select(c => c.Label).ToList() to get those labels.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • Would you put both of those interface types into the same (.cs) file in your project? – Snoop Oct 09 '17 at 12:39
  • @Evk I wouldn't see why, they are closely related, and there is no naming difference of the interfaces, for me, in this form, they belong together – Icepickle Oct 09 '17 at 12:41
  • @Snoopy well I think so too, I just mean some people would argue with that and it's not widely accepted. – Evk Oct 09 '17 at 12:42
  • @Evk What would some people propose as an alternate, though? – Snoop Oct 09 '17 at 12:46
  • @Snoopy you can see some options (including what is claimed used by Microsoft itself) in this question: https://stackoverflow.com/q/804036/5311735 – Evk Oct 09 '17 at 12:48
  • @Evk Okay, thanks for that... but I'll probably stick with doing it the way that both you and IcePickle are doing it, which seems more concise. – Snoop Oct 09 '17 at 12:51