如何将常见覆盖'TooLow'getter代码提取到单个'模板'getter?泛型?重载'<'?

时间:2013-10-02 16:22:19

标签: c# templates generics override overloading

如何将常用覆盖'TooLow'getter代码提取到单个'模板'getter?泛型?重载'<'?

get { bool rtn = _prmpt.MinValue.HasValue && (_prmpt.ResultValue < _prmpt.MinValue); return rtn; }

目标是只使用此代码一次。但是我还没弄明白如何处理'int?'和'十进制?'使用泛型正确调用.HasValue< 。 。 。建议?提前谢谢。

    /// <summary>
    /// abstracted Generic Prompt Base
    /// </summary>
    public abstract class GenPromptBase
    {
        public string InputValueType { get; set; }
        public abstract bool TooLow { get; }
    }

    /// <summary>
    /// Derived Generic 'Money' class of 'GenPromptBase'
    /// </summary>
    public class GenPromptMoney : GenPromptBase
    {
        PromptMoney _prmpt;
        public GenPromptMoney(PromptMoney prmptParms)
        {
            _prmpt = prmptParms;
            InputValueType = _prmpt.InputValueType;
        }
        public override void ParseInput(string result)
        {
            _prmpt.ResultValue = decimal.Parse(result);
        }
        public override bool TooLow
        {
            get
            {
                bool rtn = _prmpt.MinValue.HasValue && (_prmpt.ResultValue < _prmpt.MinValue);
                return rtn;
            }
        }
    }

    /// <summary>
    /// Derived Generic 'Value' class of 'GenPromptBase'
    /// </summary>
    public class GenPromptValue : GenPromptBase
    {
        PromptValue _prmpt;
        public GenPromptValue(PromptValue prmptParms)
        {
            _prmpt = prmptParms;
            InputValueType = _prmpt.InputValueType;
        }
        public override void ParseInput(string result)
        {
            _prmpt.ResultValue = int.Parse(result);
        }
        public override bool TooLow
        {
            get
            {   bool rtn = _prmpt.MinValue.HasValue && (_prmpt.ResultValue < _prmpt.MinValue);
                return rtn;
            }
        }
    }

    /// <summary>
    /// Generic Prompt Class 
    /// </summary>
    public class GenPrompt<Z>
    {
        public string InputValueType { get; set; }
        public Z MinValue;
        public Z MaxValue;
    }

    /// <summary>
    /// Derived 'Money' class of 'GenPrompt« decimal? »'
    /// </summary>
    public class PromptMoney : GenPrompt<decimal?>
    {
        public PromptMoney(
                            decimal? minValue = null,
                            decimal? maxValue = null, 
                            string inputValueType = Constants.U_GOI_FORMAT_OPTION_MONEY)
        {
            InputValueType = inputValueType;
            MinValue = minValue;
            MaxValue = maxValue;
            ResultValue = null;
        }
        public decimal? ResultValue;
    }

    /// <summary>
    /// Derived 'Value' class of 'GenPrompt« int? »'
    /// </summary>
    public class PromptValue : GenPrompt<int?>
    {
        public PromptValue(
                int? minValue = null,
                int? maxValue = null, 
                string inputValueType = Constants.U_GOI_FORMAT_OPTION_NUMBER)
        {
            InputValueType = inputValueType;
            MinValue = minValue;
            MaxValue = maxValue;
            ResultValue = null;
        }
        public int? ResultValue;
    }

2 个答案:

答案 0 :(得分:1)

尝试将Nullables和比较内容移动到GenPrompt:

public static class Constants
{
    public const string U_GOI_FORMAT_OPTION_MONEY = "";
    public const string U_GOI_FORMAT_OPTION_NUMBER = "";
}

/// <summary>
/// abstracted Generic Prompt Base
/// </summary>
public abstract class GenPromptBase
{
    public string InputValueType { get; set; }
    public abstract bool TooLow { get; }

    public abstract void ParseInput(string result);
}

/// <summary>
/// Derived Generic 'Money' class of 'GenPromptBase'
/// </summary>
public class GenPromptMoney : GenPromptBase
{
    PromptMoney _prmpt;
    public GenPromptMoney(PromptMoney prmptParms)
    {
        _prmpt = prmptParms;
        InputValueType = _prmpt.InputValueType;
    }
    public override void ParseInput(string result)
    {
        _prmpt.ResultValue = decimal.Parse(result);
    }
    public override bool TooLow
    {
        get
        {
            return _prmpt.TooLow;
        }
    }
}

/// <summary>
/// Derived Generic 'Value' class of 'GenPromptBase'
/// </summary>
public class GenPromptValue : GenPromptBase
{
    PromptValue _prmpt;
    public GenPromptValue(PromptValue prmptParms)
    {
        _prmpt = prmptParms;
        InputValueType = _prmpt.InputValueType;
    }
    public override void ParseInput(string result)
    {
        _prmpt.ResultValue = int.Parse(result);
    }
    public override bool TooLow
    {
        get
        {
            return _prmpt.TooLow;
        }
    }
}

/// <summary>
/// Generic Prompt Class 
/// </summary>
public class GenPrompt<Z> where Z: struct, IComparable
{
    public string InputValueType { get; set; }
    public Z? MinValue;
    public Z? ResultValue;
    public Z? MaxValue;
    public bool TooLow
    {
        get
        {
            return this.MinValue.HasValue && (this.MinValue.Value.CompareTo(this.ResultValue.Value) >= 0);
        }
    }
}

/// <summary>
/// Derived 'Money' class of 'GenPrompt« decimal? »'
/// </summary>
public class PromptMoney : GenPrompt<decimal>
{
    public PromptMoney(
                        decimal? minValue = null,
                        decimal? maxValue = null,
                        string inputValueType = Constants.U_GOI_FORMAT_OPTION_MONEY)
    {
        InputValueType = inputValueType;
        MinValue = minValue;
        MaxValue = maxValue;
        ResultValue = null;
    }
}

/// <summary>
/// Derived 'Value' class of 'GenPrompt« int? »'
/// </summary>
public class PromptValue : GenPrompt<int>
{
    public PromptValue(
            int? minValue = null,
            int? maxValue = null,
            string inputValueType = Constants.U_GOI_FORMAT_OPTION_NUMBER)
    {
        InputValueType = inputValueType;
        MinValue = minValue;
        MaxValue = maxValue;
        ResultValue = null;
    }
}

答案 1 :(得分:0)

使用PashaPash提供的解决方案(上面的第一个答案)。

以下是所有常见代码逻辑仅在DisplayPromptForValue()内存在一次的工作示例。

    /// <summary>
    /// prompt for dollar input
    /// <para>» inputs and return are 'decimal?' type</para>
    /// </summary>
    public decimal? DisplayPromptForMoney(string promptText, decimal? minValue = null, decimal? maxValue = null)   
    {
        PromptMoney pmptMoney = new PromptMoney(promptText, minValue, maxValue);
        DisplayPromptForValue(pmptMoney);
        return pmptMoney.ResultValue;
    }

    /// <summary>
    /// prompt for plain number input
    /// <para>» inputs and return are 'int?' type</para>
    /// </summary>
    public int? DisplayPromptForNumber(string promptText, int? minValue = null, int? maxValue = null)        
    {
        PromptNumber prmptNumber = new PromptNumber(promptText, minValue, maxValue);
        DisplayPromptForValue(prmptNumber);
        return prmptNumber.ResultValue;
    }

    /// <summary>
    /// common logic generic wrapper:  
    /// <para>'DisplayPromptForValue()' for 'InternalShowPrompt()</para>
    /// <para>common input logic for:</para>
    /// <para>+ plain number :GenPromptBase«int» ..._OPTION_NUMBER)</para>
    /// <para>+ amount       :GenPromptBase«decimal» ..._OPTION_MONEY)</para>
    /// </summary>
    public void DisplayPromptForValue<T>(GenPromptBase<T> genPmpt) where T : struct, IComparable
    {
        var parameters = MakeParameters(genPmpt.PromptText, false);
        parameters[Constants.FORMAT_TYPE] = genPmpt.InputValueType;

        bool ok;

        do
        {
            string result;
            ok = MakePrompt(parameters, out result);

            if (ok)
            {
                genPmpt.ParseInput(result);

                if (genPmpt.TooLow)
                {
                    MsgPopUp(string.Format("must be at least:{0}", genPmpt.MinValFmt));
                    continue;
                }

                if (genPmpt.TooHigh)
                {
                    MsgPopUp(string.Format("can not be over:{0}", genPmpt.MaxValFmt));
                    continue;
                }

                // input meets requirements, end input query loop
                break;
            }
        }
        while (!ok);
    }


    /// <summary>
    /// abstracted Generic Prompt Base
    /// </summary>
    public abstract class GenPromptBase<T> where T : struct, IComparable
    {
        public GenPromptBase(string inputValueType, string promptText, T? minValue = null, T? maxValue = null)
        {
            InputValueType = inputValueType;
            PromptText = promptText;
            MinValue = minValue;
            MaxValue = maxValue;
            ResultValue = null;
        }

        public abstract void ParseInput(string result);

        public string InputValueType;
        public string PromptText;

        public T? MinValue;     // inputted value
        public T? MaxValue;     // inputted value

        public T? ResultValue;  // returned value 

        public bool TooLow
        {
            get //  ComapareTo     0:  obj == MinValue            obj == ResultValue
            {   //                >0:  obj then MinValue
                //                <0:  MinValue then obj
                return this.MinValue.HasValue && (this.MinValue.Value.CompareTo(this.ResultValue.Value) > 0);
            }
        }
        public bool TooHigh
        {
            get //  ComapareTo     0:  obj == MaxValue            obj == ResultValue
            {   //                >0:  obj then MaxValue
                //                <0:  MaxValue then obj
                return this.MaxValue.HasValue && (this.MaxValue.Value.CompareTo(this.ResultValue.Value) < 0);
            }
        }
        public string MinValFmt
        {
            get { return string.Format("{0}", this.MinValue.Value); }
        }
        public string MaxValFmt
        {
            get { return string.Format("{0}", this.MaxValue.Value); }
        }
    }

    /// <summary>
    /// Derived Generic 'Money' class of 'GenPromptBase'
    /// <para>Money based logic uses 'decimal?' type.</para>
    /// <para>This derived class insulates (makes internal to itself) all</para>
    /// <para>'Money' and 'decimal?' specific logic.</para>
    /// </summary>
    public class PromptMoney : GenPromptBase<decimal>
    {
        public PromptMoney(string promptText,
                            decimal? minValue = null,
                            decimal? maxValue = null)
            : base(Constants.U_GOI_FORMAT_OPTION_MONEY, promptText, minValue, maxValue)
        { }

        public override void ParseInput(string result)
        {
            ResultValue = decimal.Parse(result);
        }
    }

    /// <summary>
    /// Derived Generic 'Number' class of 'GenPromptBase'
    /// <para>Value, as plain number, based logic uses 'int?' type.</para>
    /// <para>This derived class insulates (makes internal to itself) all</para>
    /// <para>'Number' and 'int?' specific logic.</para>
    /// </summary>
    public class PromptNumber : GenPromptBase<int>
    {
        public PromptNumber(string promptText,
                             int? minValue = null,
                             int? maxValue = null)
            : base(Constants.U_GOI_FORMAT_OPTION_NUMBER, promptText, minValue, maxValue)
        { }

        public override void ParseInput(string result)
        {
            ResultValue = int.Parse(result);
        }
    }