【问题标题】:How to extract common override 'TooLow' getter code to a single 'template' getter? Generics? Overload '<'?如何将通用覆盖“TooLow”吸气剂代码提取到单个“模板”吸气剂?泛型?重载'<'?
【发布时间】:2013-10-02 16:22:19
【问题描述】:

如何将通用覆盖“TooLow”getter 代码提取到单个“template”getter?泛型?重载'

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

目标是只拥有此代码一次。但是我还没有弄清楚如何处理'int?和“十进制?”使用泛型正确调用 .HasValue&lt;。 . . .建议?提前谢谢你。

    /// <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;
    }

【问题讨论】:

    标签: c# templates generics overriding overloading


    【解决方案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;
        }
    }
    

    【讨论】:

    • A+ 答案!谢谢你,帕夏帕什!请参阅下面部署 PashaPash 解决方案的第二个答案...注意:我不明白调用 DisplayPromptForValue() &lt;T&gt; 时不需要指定。
    【解决方案2】:

    使用 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);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      • 2018-11-16
      相关资源
      最近更新 更多