【问题标题】:return type must be 'bool' error返回类型必须是 'bool' 错误
【发布时间】:2018-07-22 13:53:57
【问题描述】:

我使用 xamarin android 创建了需要显示和警告框的应用程序,并根据选择的值进行一些计算。所以在菜单项点击我已经添加了下面的代码。

public override async Task<bool> OnOptionsItemSelected(IMenuItem item)
{
    bool bTotalResult = false;
    switch (item.ItemId)
    {


        case Resource.Id.action_next:
            bTotalResult = await ShowPayMentTypeDialog();

            return await Task.Run(() => true).ConfigureAwait(true); ;
        default:
            return await Task.Run(() => base.OnOptionsItemSelected(item)).ConfigureAwait(true);;
    }
    //return await Task.Run(() => false ).ConfigureAwait(true);
}
private async Task<bool> ShowPayMentTypeDialog()
{
    bool bResult = false;
    try
    {
        LayoutInflater layoutInflater = LayoutInflater.From(this);
        View view = layoutInflater.Inflate(Resource.Layout.lyt_cash_credit_popup, null);
        Android.Support.V7.App.AlertDialog.Builder alertbuilder = new Android.Support.V7.App.AlertDialog.Builder(this);
        alertbuilder.SetView(view);
        var userdata = view.FindViewById<Spinner>(Resource.Id.spnrPaymentTerms);
        List<cls_spinner_adapter> resultsWayNo = new List<cls_spinner_adapter> {
        new cls_spinner_adapter {SZ_SPINNER_TEXT ="CASH"},
       new cls_spinner_adapter {SZ_SPINNER_TEXT ="CREDIT" } };
        CommonSpinnerAdapter paymentAdapter = new CommonSpinnerAdapter(this, resultsWayNo);
        userdata.Adapter = paymentAdapter;
        alertbuilder.SetCancelable(false)
        .SetPositiveButton("OK", delegate
        {
            if (resultsWayNo[userdata.SelectedItemPosition].SZ_SPINNER_TEXT == "CASH")
            {
                cls_statics.B_IS_PROMOMAYMANET_CASH = true;
            }
            else
            {
                cls_statics.B_IS_PROMOMAYMANET_CASH = false;
            }
            bResult = true;
        })
        .SetNegativeButton("Cancel", delegate
        {
            cls_statics.B_IS_PROMOMAYMANET_CASH = false;
            bResult = true;
            alertbuilder.Dispose();

        });
        Android.Support.V7.App.AlertDialog dialog = alertbuilder.Create();
        dialog.Show();
    }
    catch
    {

    }
    return await Task.Run(() => bResult).ConfigureAwait(true);
}

但是在编译时我遇到了错误。

返回类型必须为 'bool' 以匹配被覆盖的成员 Activity.OnOptionsItemSelected(IMenuItem)

【问题讨论】:

标签: c# xamarin async-await


【解决方案1】:

贴出的代码有几个问题,我们来看看。

  1. 正如编译器告诉您的那样,您无法更改要覆盖的方法的签名。因此,将您的方法更改为:

    override bool OnOptionsItemSelected
    
  2. .ConfigureAwait(true);默认配置,不需要显式调用。

  3. 以下行不必要地启动一个新的线程池线程,只是为了返回一个常量值:

    return await Task.Run(() => true)
    

    该代码应该只是:

    return true;
    
  4. 不应将同步代码标记为异步以尝试使其异步。相反,如果需要,调用者必须以异步方式调用它们。您应该熟悉 Stephen Cleary 的这篇优秀文章:Task.Run Etiquette Examples: Don't Use Task.Run in the Implementation

所以,让我们把所有这些放在一起:

//Point 1
public override bool OnOptionsItemSelected(IMenuItem item)
{
    bool bTotalResult = false;

    switch (item.ItemId)
    {
        case Resource.Id.action_next:
            bTotalResult = Task.Run(() => ShowPayMentTypeDialog()).Result;

            // point 3
            return true;
        default:
            // point 3
            return base.OnOptionsItemSelected(item);
    }
}

// point 4
private bool ShowPayMentTypeDialog()
{
    bool bResult = false;
    try
    {
        LayoutInflater layoutInflater = LayoutInflater.From(this);
        View view = layoutInflater.Inflate(Resource.Layout.lyt_cash_credit_popup, null);
        Android.Support.V7.App.AlertDialog.Builder alertbuilder = new Android.Support.V7.App.AlertDialog.Builder(this);
        alertbuilder.SetView(view);
        var userdata = view.FindViewById<Spinner>(Resource.Id.spnrPaymentTerms);
        List<cls_spinner_adapter> resultsWayNo = new List<cls_spinner_adapter> {
        new cls_spinner_adapter {SZ_SPINNER_TEXT ="CASH"},
       new cls_spinner_adapter {SZ_SPINNER_TEXT ="CREDIT" } };
        CommonSpinnerAdapter paymentAdapter = new CommonSpinnerAdapter(this, resultsWayNo);
        userdata.Adapter = paymentAdapter;
        alertbuilder.SetCancelable(false)
        .SetPositiveButton("OK", delegate
        {
            if (resultsWayNo[userdata.SelectedItemPosition].SZ_SPINNER_TEXT == "CASH")
            {
                cls_statics.B_IS_PROMOMAYMANET_CASH = true;
            }
            else
            {
                cls_statics.B_IS_PROMOMAYMANET_CASH = false;
            }
            bResult = true;
        })
        .SetNegativeButton("Cancel", delegate
        {
            cls_statics.B_IS_PROMOMAYMANET_CASH = false;
            bResult = true;
            alertbuilder.Dispose();

        });
        Android.Support.V7.App.AlertDialog dialog = alertbuilder.Create();
        dialog.Show();
    }
    catch
    {

    }

    // point 3
    return bResult;
}

【讨论】:

  • 嗨,这里出现错误 Task.Run(() => ShowPayMentTypeDialog()).Wait() 无法将类型“void”隐式转换为“bool”
  • @Rakesh 我的错,应该是.Result
  • .ConfigureAwait(true); - 我猜他正在使用 StyleCop/FxCop 并且它被配置为期望它是明确的。
  • @Neil ReSharper 或其他扩展名。我一直在一个项目中使用了所有 StyleCop 和 FxCop 规则,他们都没有要求你做这样一个无用的电话
  • @Camilo : .Result 给出了这个错误 Binary XML file line #1: Error inflating class Spinner
猜你喜欢
  • 1970-01-01
  • 2017-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
相关资源
最近更新 更多