views:

65

answers:

1

So, first I have my command property interface

public interface ICommandProperty<T, U>
{
    Func<T> CreateCommand { get; set; }
    Func<T, U> ParseResponse { get; set; }
}

The idea is that I can create a simple parser that takes a string and returns an IPAddress for example.

This interface is then used in another interface:

public interface IDeviceCommand
{

    Func<ICommandProperty<object, object>> SetCommand
    {
        get;
        set;
    }
    Func<ICommandProperty<object, object>> GetCommand
    {
        get;
        set;
    }
    string Name { get; set; }
}

I may be going about this all wrong, but this is where I have the problem. Currently I have the generic interface declared with objects because I can't figure out a way to set them generically(IDeviceCommand can't be generic for various reasons).

My concrete implementation looks like this:

public class DeviceCommand:IDeviceCommand 
{
    public DeviceCommand(string name,Func<ICommandProperty<object,object>> Set,Func<ICommandProperty<object,object>> Get)
    {
        this.Name = name;
        this.SetCommand = Set;
        this.GetCommand = Get;
    }
    #region IDeviceCommand Members
    public string Name
    {
        get;
        set;
    }
    public object Value
    {
        get;
        set;
    }
    public Func<ICommandProperty<object, object>> SetCommand
    {
        get;
        set;
    }
    public Func<ICommandProperty<object, object>> GetCommand
    {
        get;
        set;
    }
    #endregion
}

I could make DeviceCommand be a generic class, and use T,U on the SetCommand and GetCommand, but then it doesn't satisfy the IDeviceCommand interface because Func<ICommandProperty<T,U>> isn't Func<ICommandProperty<object,object>>

Is there a different approach that I should be using here. In essence I'm trying to create a method pointer that I can set when I instantiate DeviceCommand.

+1  A: 

Your questions seems a little vague, but here's some ideas. The first is to consider using methods instead of properties so that they can be generic rather than the class. Not sure if that will work for you. You could also consider passing a "builder" object into your Device command rather than the func<>'s themselves. Lastly, this gets hairy with your client knowing what to ask for and ensuring it is working with an object that has the correct func<> available. In that case, maybe something like the IDeviceCommand.Create and .Parse methods could work for you.

Lastly, if you are always looking for something to take a string and return an IP, the generics may not be necessary. Even plain old delegates could be explored.

public interface ICommandProperty<T, U>
    {
        Func<T> CreateCommand { get; set; }
        Func<T, U> ParseResponse { get; set; }
    }

    public interface IDeviceCommand
    {

        void SetCreateCommand<T, U>(Func<ICommandProperty<T, U>> cmd);
        void SetParseCommand<T, U>(Func<ICommandProperty<T, U>> cmd);

        Func<ICommandProperty<T, U>> GetCreateCommand<T, U>();
        Func<ICommandProperty<T, U>> GetParseCommand<T, U>();

        void Create(object someKnownObject);
        T Parse<T>(object someKnownObject);

        string Name { get; set; }
    }

    public class DeviceCommand : IDeviceCommand
    {
        public DeviceCommand(IDeviceCommandBuilder builder)
        {
            builder.SetCommands(this);
        }


        public void SetCreateCommand<T, U>(Func<ICommandProperty<T, U>> cmd)
        {
            throw new NotImplementedException();
        }

        public void SetParseCommand<T, U>(Func<ICommandProperty<T, U>> cmd)
        {
            throw new NotImplementedException();
        }

        public Func<ICommandProperty<T, U>> GetCreateCommand<T, U>()
        {
            throw new NotImplementedException();
        }

        public Func<ICommandProperty<T, U>> GetParseCommand<T, U>()
        {
            throw new NotImplementedException();
        }

        public void Create(object someKnownObject)
        {
            throw new NotImplementedException();
        }

        public T Parse<T>(object someKnownObject)
        {
            throw new NotImplementedException();
        }

        public string Name
        {
            get { throw new NotImplementedException(); }
            set { throw new NotImplementedException(); }
        }
    }

    public interface IDeviceCommandBuilder
    {
        void SetCommands(IDeviceCommand command);
    }

    public class DeviceCommandBuilder : IDeviceCommandBuilder
    {
        public void SetCommands(IDeviceCommand command)
        {
            command.SetCreateCommand<string,Uri>(.)
            ;
            command.SetParseCommand(.);
        }
    }
Corey Coogan
Corey, thanks for the response you got the jist of what I'm after for sure. You're right the main issue is that client doesn't necessarily know the types to ask for. So, when I use IDeviceCommand.GetCreateCommand<T,U>() the caller isn't going to know what types to pass for T,U.
BigTundra