代码之家  ›  专栏  ›  技术社区  ›  Razzupaltuff

允许算术运算的通用剃须刀组件

  •  1
  • Razzupaltuff  · 技术社区  · 4 年前

    我想创建一个剃刀组件,允许输入int或float数字,并使用旋转控件递增或递减它们。然而,我不知道如何告诉Blazor生成器/C#编译器如何处理传递给组件的值的算术运算,因为类型是泛型的。我需要做些什么才能使这样的操作成为可能?

    这是我的代码:

    @typeparam TValue
    
    @code {
        [Parameter]
        public TValue Value { get; set; }
    
        [Parameter]
        public EventCallback<TValue> ValueChanged { get; set; }
    
        public void SpinUp() { Value += (TValue) 1; }
    
        public void SpinDown() { Value -= (TValue) 1; }
    }
    

    据我所知,在编译时,通用组件中没有关于TValue是否支持数字运算的信息。问题是如何告诉编译器,TValue必须始终是数字数据类型(例如,受某些限制)?

    为了简短起见,我省略了所有的HTML,因为它说明了这个问题。SpinUp()和SpinDown()是由两个按钮组成的控件的回调函数,您可以单击这两个按钮来增加或减少数字文本框中的值。

    0 回复  |  直到 4 年前
        1
  •  2
  •   MrC aka Shaun Curtis    4 年前

    看起来有点长篇大论,但是:

    很高兴有任何缩短它的方法!

    @typeparam TValue
    <div>
        <button class="btn btn-danger" @onclick=SpinDown>-</button>
        <button class="btn btn-success" @onclick=SpinUp>+</button>
    </div>
    
    <div>
        Value = @Value?.ToString()
    </div>
    @code {
        [Parameter]
        public TValue? Value { get; set; }
    
        [Parameter]
        public EventCallback<TValue> ValueChanged { get; set; }
    
        private void SpinUp()
        {
            TValue value;
            switch (Value)
            {
                case int val:
                    val++;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case long val:
                    val++;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case short val:
                    val++;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case decimal val:
                    val++;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case float val:
                    val++;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case double val:
                    val++;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                default:
                    throw new Exception("Can't do maths operations on the type suplied");
    
            };
    
            ValueChanged.InvokeAsync(value);
        }
    
        private void SpinDown()
        {
            TValue value;
            switch (Value)
            {
                case int val:
                    val--;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case long val:
                    val--;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case short val:
                    val--;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case decimal val:
                    val--;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case float val:
                    val--;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                case double val:
                    val--;
                    value = (TValue)Convert.ChangeType(val, typeof(TValue));
                    break;
    
                default:
                    throw new Exception("Can't do maths operations on the type suplied");
    
            };
    
            ValueChanged.InvokeAsync(value);
        }
    }
    

    我的测试页面:

    @page "/"
    
    <PageTitle>Index</PageTitle>
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    <SurveyPrompt Title="How is Blazor working for you?" />
    
    <Spinner @bind-Value=value/>
    
    <div>
        Value : @value.ToString()
    </div>
    @code {
        private double value = 0;
    }
    
        2
  •  2
  •   Mister Magoo    4 年前

    如果你愿意使用.NET7预览位,你可以这样做

    public partial class NumericThing<TValue>  where TValue : INumber<TValue>
    {
        [Parameter]
        public TValue Value { get; set; }
            
        [Parameter]
        public EventCallback<TValue> ValueChanged { get; set; }
    
        public void SpinUp()
        {           
            Value += TValue.CreateChecked(1);
        }
    
        public void SpinDown()
        {
            Value -= TValue.CreateChecked(1);
        }
    }