这种bool方法是一种不好的做法吗?

时间:2016-07-15 10:34:01

标签: c# performance xna

有时我发现自己写的bool方法看起来像这样:

public bool isRunning()
    {
        if (!(move == Moving.None) && staminaRegan == true)
        {
            if (keyState.IsKeyDown(Keys.Space))
            {
                EntityAnimation.interval = 10;
                return true;
            }
            else
            {
                EntityAnimation.interval = 65;
                return false;
            }
        }
        else 
        {
            EntityAnimation.interval = 65;
            return false;
        }
    }

(顺便说一下这是XNA)正如你所看到的,我有一个bool isRunning,其中我做了一个if语句,我在那里检查是否(播放器正在移动)&& (恢复耐力,一旦耐力达到小于6.0f的值,则设定为假) 然后我只是检查空间是否被按下,如果是,那么我的动画更快(间隔越小,spritesheet更改越快),然后它发送真值,这意味着播放器正在运行,否则我不是因为空间是没有按下。

然后我必须重复这个'否则'代码在第一个if语句之外,所以如果Player没有移动或者他的耐力Regan是假的话,它会发送Player没有运行;

所以我只是想知道这种bool方法被认为是一种不好的做法(你在嵌套if中重新使用true和false值,然后在嵌套之外返回false,如果重复相同的代码)?

5 个答案:

答案 0 :(得分:7)

该方法有副作用,这就是不良做法的原因:

    public MultipleModeCallBack(BaseActivity activity, View view, ListView listview, StorageListViewModel vm)
    {
        _activity = activity;
        _view = view;
        _listView = listview;
        _vm = vm;
        _multiButton = _view.FindViewById<FloatingActionButton>(Resource.Id.MultipleSelectionActionButton);
        _multiButton.Click += ToggleButtonClick;
        _plusButton = _view.FindViewById<FloatingActionButton>(Resource.Id.PlusButton);

        if (selectedNodes == null)
            selectedNodes = new List<StorageItemViewModel>();
    }

    public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
    {
        return true;
    }

    public bool OnCreateActionMode(ActionMode mode, IMenu menu)
    {
        _mode = mode;

        for (var i = 0; i < _listView.ChildCount; i++)
        {
            var view = _listView.GetChildAt(i);
            var holder = (FilesPageFragment.FileStorageItemHolder)view.Tag;
            holder.Button.Visibility = ViewStates.Gone;
        }

        _plusButton.Visibility = ViewStates.Gone;
        _multiButton.Visibility = ViewStates.Visible;

        return true;
    }
    public void OnDestroyActionMode(ActionMode mode)
    {
        _plusButton.Visibility = ViewStates.Visible;
        _multiButton.Visibility = ViewStates.Gone;

        for (var i = 0; i < _listView.Adapter.Count; i++)
        {
            var view = _listView.GetChildAt(i);
            var holder = (FilesPageFragment.FileStorageItemHolder)view.Tag;
            DisplayItems(holder, false, i);
            holder.Button.Visibility = ViewStates.Visible;
        }
        selectedNodes.Clear();
    }

    private void DisplayItems(FilesPageFragment.FileStorageItemHolder holder, bool @checked, int position)
    {
        if (@checked)
        {
            holder.Icon.SetImageResource(Resource.Drawable.ic_check_white_24dp);
            holder.Icon.SetPadding(0, 0, 0, 0);
            holder.Icon.SetBackgroundResource(Resource.Drawable.multiple_check);
            holder.Icon.SetColorFilter(Graphics.Color.White);
        }
        else
        {
            holder.Icon.SetImageResource(Android.App.Utility.AndroidResource.GetIconChar(_vm.StorageList[position].Type));
            holder.Icon.Background = null;
            holder.Icon.SetColorFilter(new Color(Android.Support.V4.Content.ContextCompat.GetColor(_activity.BaseContext, Resource.Color.accent)), PorterDuff.Mode.SrcAtop);
        }
    }

    public void OnItemCheckedStateChanged(ActionMode mode, int position, long id, bool @checked)
    {
        IsDownloadEnable = true;
        var positions = _listView.CheckedItemPositions;
        if (positions != null)
        {
            var view = _listView.GetChildAt(position);
            DisplayItems((FilesPageFragment.FileStorageItemHolder)view.Tag, @checked, position);

            var length = positions.Size();
            for (var i = 0; i < length; i++)
            {
                if (positions.Get(positions.KeyAt(i)))
                {
                    if (!selectedNodes.Any(item => item.UniqueId == _vm.StorageList[positions.KeyAt(i)].UniqueId))
                        selectedNodes.Add(_vm.StorageList[positions.KeyAt(i)]);
                    if (_vm.StorageList[positions.KeyAt(i)].IsDirectory)
                        IsDownloadEnable = false;
                }
                else
                {
                    selectedNodes.Remove(_vm.StorageList[positions.KeyAt(i)]);
                }
            }
        }
        mode.Title = $"{selectedNodes.Count} items selected";

    }

    public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
    {
        return true;
    }

在查看方法的签名时,我们只希望 public bool isRunning() / true回答。但是,方法更改实例的状态

false

我建议将初始方法拆分为属性和方法

  ...
  if (!(move == Moving.None) && staminaRegan == true)
    {
        if (keyState.IsKeyDown(Keys.Space))
        {
            EntityAnimation.interval = 10; // <- Aaa! The interval is changed 
            return true;
        }
  ...

答案 1 :(得分:1)

在方法中包含一个return语句是一个好习惯。有人争论这个,但这是一个意见。

通过删除不必要的代码来清除if语句也是一种很好的做法:

public bool isRunning()
{
    bool result = false;
    if (move != Moving.None && staminaRegan)
    {
        if (keyState.IsKeyDown(Keys.Space))
        {
            EntityAnimation.interval = 10;
            result = true;
        }
        else
        {
            EntityAnimation.interval = 65;
        }
    }
    else
    {
        EntityAnimation.interval = 65;
    }

    return result;
}

答案 2 :(得分:1)

您可以按如下方式重写代码;那么代码不会重复:

public bool isRunning()
{
    if (move != Moving.None && staminaRegan && keyState.IsKeyDown(Keys.Space))
    {
        EntityAnimation.interval = 10;
        return true;
    }
    else
    {
        EntityAnimation.interval = 65;
        return false;
    }
}

或者如果您不想要多余的else

public bool isRunning()
{
    if (move != Moving.None && staminaRegan && keyState.IsKeyDown(Keys.Space))
    {
        EntityAnimation.interval = 10;
        return true;
    }

    EntityAnimation.interval = 65;
    return false;
}

我会考虑引入一个名为boolean的自我文档,我会将staminaRegan重命名为staminaIsRegenerating

public bool isRunning()
{
    bool isMovingQuickly = (move != Moving.None) && staminaIsRegenerating && keyState.IsKeyDown(Keys.Space);

    if (isMovingQuickly)
        EntityAnimation.interval = 10;
    else
        EntityAnimation.interval = 65;

    return isMovingQuickly;
}

但最重要的是,您应该重命名该方法以更准确地描述它正在做的事情:

public bool CheckIfRunningAndSetAnimationInterval()

答案 3 :(得分:1)

我认为我们为人(其他开发人员)编写代码,当然机器执行代码但是80%的开发人员正在阅读代码。
基于此,我认为阅读流程必须与执行代码的流程完全相同 - 这就是为什么我认为乘以return语句并不是坏事,甚至更好的只有一个返回语句在你的底部方法。

答案 4 :(得分:0)

我喜欢这种风格,我也使用它。首先,您可以更轻松地阅读代码,其次它具有调试优势,因为您可以为其他个案设置断点。否则你需要使用断点条件。