条件运算符与逻辑运算符评估之间的区别 [英] Difference Between Conditional and Logical Operator Evaluation

查看:112
本文介绍了条件运算符与逻辑运算符评估之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在弄清楚应用程序中if else语句的正确实现时遇到麻烦.当前,我使用条件运算符&&||进行比较,但是当我的应用程序在市场中启动时,我的代码未按计划运行.从本质上讲,它应该工作的方式是:如果计数大于100并且该应用程序仍为试用许可证,则要求升级;否则,如果计数小于或等于100并且该应用程序仍为试用许可证或该应用程序是完整许可证,然后允许执行ApplyAndSaveAsync方法.

I am having trouble figuring out the proper implementation of an if else statement in my application. Currently I am using the conditional operators && and || for comparison, but when my application is launched in the marketplace my code is not operating as planned. Essentially the way it should work is that if the count is greater than 100 and the application is still a trial license then ask to upgrade, otherwise if the count is less than or equal to 100 and the application is still a trial license OR the application is a full license then allow ApplyAndSaveAsync method to execute.

Settings.SavedCount.Value += 1;
        if ((Settings.SavedCount.Value > 100) && (TrialViewModel.LicenseModeString == "Trial"))
        {
            MessageBoxResult result = MessageBox.Show("You have saved over 100 items! Would you like to continue?", "Congratulations", MessageBoxButton.OKCancel);
            switch (result)
            {
                case MessageBoxResult.OK:
                    // A command takes a parameter and in this case we can pass null.
                    TrialViewModel.BuyCommand.Execute(null);
                    break;
                case MessageBoxResult.Cancel:
                    return;
                    break;
            }
        }
        else if (((Settings.SavedCount.Value <= 100) && (TrialViewModel.LicenseModeString == "Trial")) || (TrialViewModel.LicenseModeString == "Full"))
        {
            ApplyAndSaveAsync();
        }

请注意,在字符串比较中,TrialViewModel.LicenseModeString可以为TrialFull,并且似乎工作正常. Settings.SavedCount.Value也同样正确地递增. TrialViewModel.LicenseModeString是查询许可证状态,该状态是在应用程序中自动设置的,无论用户是下载试用版还是完整版,或者当用户将试用版升级到完整版时,所以我认为这不是问题.出于某种原因,尽管在市场上以试用和完整状态测试我的应用程序时,ApplyAndSaveAsync方法从不执行?

To note, TrialViewModel.LicenseModeString can either be Trial or Full in the string comparison and it seems to be working properly. Settings.SavedCount.Value is also incrementing properly as well. TrialViewModel.LicenseModeString is queries the license state which is automatically set in the application whether the user downloads a trial or full version, or when a user upgrades a trial to the full version, so I do not think this is the issue. For some reason though when testing my app in both Trial and Full states from the Marketplace, the ApplyAndSaveAsync method never executes?

我尝试反转TrialViewModel.LicenseModeStringSettings.Saved.Count.Value的检查,因此将首先检查计数,但是我不确定这是否有帮助.我引用了 http://msdn.microsoft.com/en-us/library/aa691310(v = vs.71).aspx 指出The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true. The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is false.因此,我不确定下面的陈述是否可以正常工作?

I have tried reversing the check of TrialViewModel.LicenseModeString and Settings.Saved.Count.Value so the count will be checked first, but I'm not sure if this would help. I referenced http://msdn.microsoft.com/en-us/library/aa691310(v=vs.71).aspx which states that The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true. The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is false. So I am not sure if my statement below will work appropriately?

Settings.SavedCount.Value += 1;
        if ((Settings.SavedCount.Value > 100) && (TrialViewModel.LicenseModeString == "Trial"))
        {
            //MessageBoxResult result = MessageBox.Show("You have saved over 100 filtered pictures! Would you like to continue?", "Congratulations", MessageBoxButton.OKCancel);
            MessageBoxResult result = MessageBox.Show(AppResources.EditPage_MessageBoxContent_Purchase, AppResources.EditPage_MessageBoxCaption_Purchase, MessageBoxButton.OKCancel);
            switch (result)
            {
                case MessageBoxResult.OK:
                    // A command takes a parameter and in this case we can pass null.
                    TrialViewModel.BuyCommand.Execute(null);
                    break;
                case MessageBoxResult.Cancel:
                    if (editPagePivotControl != null && editPagePivotControl.SelectedIndex != 0)
                    {
                        //trialPopup.IsOpen = false;
                        editPagePivotControl.SelectedIndex = 0;
                    }
                    break;
            }
        }
        else if (((Settings.SavedCount.Value <= 100) && (TrialViewModel.LicenseModeString == "Trial")) || (TrialViewModel.LicenseModeString == "Full"))
        {
            ApplySelectedEffectAndSaveAsync();
        }

最后一个问题是,我应该使用单个&|运算符代替吗?

And my final question is should I use a single & and | operators instead?

Settings.SavedCount.Value += 1;
        if ((Settings.SavedCount.Value > 1) & (TrialViewModel.LicenseModeString == "Trial"))
        {
            //MessageBoxResult result = MessageBox.Show("You have saved over 100 filtered pictures! Would you like to continue?", "Congratulations", MessageBoxButton.OKCancel);
            MessageBoxResult result = MessageBox.Show(AppResources.EditPage_MessageBoxContent_Purchase, AppResources.EditPage_MessageBoxCaption_Purchase, MessageBoxButton.OKCancel);
            switch (result)
            {
                case MessageBoxResult.OK:
                    // A command takes a parameter and in this case we can pass null.
                    TrialViewModel.BuyCommand.Execute(null);
                    break;
                case MessageBoxResult.Cancel:
                    if (editPagePivotControl != null && editPagePivotControl.SelectedIndex != 0)
                    {
                        //trialPopup.IsOpen = false;
                        editPagePivotControl.SelectedIndex = 0;
                    }
                    break;
            }
        }
        else if (((Settings.SavedCount.Value <= 1) & (TrialViewModel.LicenseModeString == "Trial")) | (TrialViewModel.LicenseModeString == "Full"))
        {
            ApplySelectedEffectAndSaveAsync();
        }

TrialViewModel

TrialViewModel

#region fields
    private RelayCommand buyCommand;
    #endregion fields

    #region constructors
    public TrialViewModel()
    {
        // Subscribe to the helper class's static LicenseChanged event so that we can re-query its LicenseMode property when it changes.
        TrialExperienceHelper.LicenseChanged += TrialExperienceHelper_LicenseChanged;
    }
    #endregion constructors

    #region properties        
    /// <summary>
    /// You can bind the Command property of a Button to BuyCommand. When the Button is clicked, BuyCommand will be
    /// invoked. The Button will be enabled as long as BuyCommand can execute.
    /// </summary>
    public RelayCommand BuyCommand
    {
        get
        {
            if (this.buyCommand == null)
            {
                // The RelayCommand is constructed with two parameters - the action to perform on invocation,
                // and the condition under which the command can execute. It's important to call RaiseCanExecuteChanged
                // on a command whenever its can-execute condition might have changed. Here, we do that in the TrialExperienceHelper_LicenseChanged
                // event handler.
                this.buyCommand = new RelayCommand(
                    param => TrialExperienceHelper.Buy(),
                    param => TrialExperienceHelper.LicenseMode == TrialExperienceHelper.LicenseModes.Trial);
            }
            return this.buyCommand;
        }
    }

    public string LicenseModeString
    {
        get
        {
            return TrialExperienceHelper.LicenseMode.ToString()/* + ' ' + AppResources.ModeString*/;
        }
    }
    #endregion properties

    #region event handlers
    // Handle TrialExperienceHelper's LicenseChanged event by raising property changed notifications on the
    // properties and commands that 
    internal void TrialExperienceHelper_LicenseChanged()
    {
        this.RaisePropertyChanged("LicenseModeString");
        this.BuyCommand.RaiseCanExecuteChanged();
    }
    #endregion event handlers

TrialExperienceHelper.cs

TrialExperienceHelper.cs

#region enums
    /// <summary>
    /// The LicenseModes enumeration describes the mode of a license.
    /// </summary>
    public enum LicenseModes
    {
        Full,
        MissingOrRevoked,
        Trial
    }
    #endregion enums

    #region fields
#if DEBUG
    // Determines how a debug build behaves on launch. This field is set to LicenseModes.Full after simulating a purchase.
    // Calling the Buy method (or navigating away from the app and back) will simulate a purchase.
    internal static LicenseModes simulatedLicMode = LicenseModes.Trial;
#endif // DEBUG
    private static bool isActiveCache;
    private static bool isTrialCache;
    #endregion fields

    #region constructors
    // The static constructor effectively initializes the cache of the state of the license when the app is launched. It also attaches
    // a handler so that we can refresh the cache whenever the license has (potentially) changed.
    static TrialExperienceHelper()
    {
        TrialExperienceHelper.RefreshCache();
        PhoneApplicationService.Current.Activated += (object sender, ActivatedEventArgs e) => TrialExperienceHelper.
#if DEBUG
            // In debug configuration, when the user returns to the application we will simulate a purchase.

OnSimulatedPurchase(); #else//调试 //在发布配置中,当用户返回到应用程序时,我们将刷新缓存. RefreshCache(); #endif//调试 } #endregion构造函数

OnSimulatedPurchase(); #else // DEBUG // In release configuration, when the user returns to the application we will refresh the cache. RefreshCache(); #endif // DEBUG } #endregion constructors

    #region properties
    /// <summary>
    /// The LicenseMode property combines the active and trial states of the license into a single
    /// enumerated value. In debug configuration, the simulated value is returned. In release configuration,
    /// if the license is active then it is either trial or full. If the license is not active then
    /// it is either missing or revoked.
    /// </summary>
    public static LicenseModes LicenseMode
    {
        get
        {
#if DEBUG
            return simulatedLicMode;
#else // DEBUG
            if (TrialExperienceHelper.isActiveCache)
            {
                return TrialExperienceHelper.isTrialCache ? LicenseModes.Trial : LicenseModes.Full;
            }
            else // License is inactive.
            {
                return LicenseModes.MissingOrRevoked;
            }
#endif // DEBUG
        }
    }

    /// <summary>
    /// The IsFull property provides a convenient way of checking whether the license is full or not.
    /// </summary>
    public static bool IsFull
    {
        get
        {
            return (TrialExperienceHelper.LicenseMode == LicenseModes.Full);
        }
    }
    #endregion properties

    #region methods
    /// <summary>
    /// The Buy method can be called when the license state is trial. the user is given the opportunity
    /// to buy the app after which, in all configurations, the Activated event is raised, which we handle.
    /// </summary>
    public static void Buy()
    {
        MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();
        marketplaceDetailTask.ContentType = MarketplaceContentType.Applications;
        marketplaceDetailTask.Show();
    }

    /// <summary>
    /// This method can be called at any time to refresh the values stored in the cache. We re-query the application object
    /// for the current state of the license and cache the fresh values. We also raise the LicenseChanged event.
    /// </summary>
    public static void RefreshCache()
    {
        TrialExperienceHelper.isActiveCache = CurrentApp.LicenseInformation.IsActive;
        TrialExperienceHelper.isTrialCache = CurrentApp.LicenseInformation.IsTrial;
        TrialExperienceHelper.RaiseLicenseChanged();
    }

    private static void RaiseLicenseChanged()
    {
        if (TrialExperienceHelper.LicenseChanged != null)
        {
            TrialExperienceHelper.LicenseChanged();
        }
    }

#if DEBUG
    private static void OnSimulatedPurchase()
    {
        TrialExperienceHelper.simulatedLicMode = LicenseModes.Full;
        TrialExperienceHelper.RaiseLicenseChanged();
    }
#endif // DEBUG
    #endregion methods

    #region events
    /// <summary>
    /// The static LicenseChanged event is raised whenever the value of the LicenseMode property has (potentially) changed.
    /// </summary>
    public static event LicenseChangedEventHandler LicenseChanged;
    #endregion events    

推荐答案

您的逻辑似乎还不错.您确定TrialViewModel.LicenseModeString完全返回TrialFull吗?

You logic seems ok. Are you sure TrialViewModel.LicenseModeString returns exactly Trial or Full?

顺便说一句,在您的情况下,使用&&还是&运算符都没有区别.当逻辑表达式的一部分是一种方法时,确实会有所不同.例如:

By the way, in your case it makes no difference whether you use the && or & operator. It does make a difference when one part of the logical expression is a method. For instance:

int i = 0;
if ((i >= 100) & (a.IncreaseCounter() > 5))
  // a.IncreaseCounter() will be executed even while i is less than 100

if ((i >= 100) && (a.IncreaseCounter() > 5))
  // a.IncreaseCounter() will not be excuted 

第一个if语句首先对表达式的两边求值,然后检查表达式是true还是false.第二条语句使评估短路.由于左表达式为假,因此它不会评估右侧,因为它已经知道最终结果将为假.

The first if statement first evaluates both sides of the expression and then checks if the expression is true or false. The second statement short circuits the evaluation. Because the left epression is false it does not evaluate the right side because it already knows the end result will be false.

这篇关于条件运算符与逻辑运算符评估之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆