【问题标题】:Difference Between Conditional and Logical Operator Evaluation条件和逻辑运算符评估之间的区别
【发布时间】:2013-11-02 15:27:06
【问题描述】:

我无法在我的应用程序中找出 if else 语句的正确实现。目前我使用条件运算符&&|| 进行比较,但是当我的应用程序在市场上启动时,我的代码没有按计划运行。本质上它应该工作的方式是,如果计数大于 100 并且应用程序仍然是试用许可证,则要求升级,否则如果计数小于或等于 100 并且应用程序仍然是试用许可证或应用程序是完整许可,则允许执行 ApplyAndSaveAsync 方法。

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 方法永远不会执行?

我已尝试反转检查TrialViewModel.LicenseModeStringSettings.Saved.Count.Value,因此将首先检查计数,但我不确定这是否有帮助。我引用了http://msdn.microsoft.com/en-us/library/aa691310(v=vs.71).aspx,它指出The operation x &amp;&amp; y corresponds to the operation x &amp; 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. 所以我不确定我下面的陈述是否能正常工作?

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();
        }

我的最后一个问题是我应该使用单个 &amp;| 运算符吗?

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();
        }

试用视图模型

#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

#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 // 调试 // 在发布配置中,当用户返回应用程序时,我们会刷新缓存。 刷新缓存(); #endif // 调试 } #endregion 构造函数

    #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    

【问题讨论】:

    标签: c# windows-phone-7 windows-phone-8 operators logic


    【解决方案1】:

    你的逻辑似乎没问题。您确定TrialViewModel.LicenseModeString 准确返回TrialFull

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

    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 语句首先计算表达式的两边,然后检查表达式是真还是假。第二个语句使评估短路。因为左边是假的,所以它不会评估右边,因为它已经知道最终结果是假的。

    【讨论】:

    • 好吧,这是有道理的。我添加了TrialViewModel,它使用TrialExperienceHelper.cs 来确定当前的应用程序许可证状态。也许你能看到我忽略的东西?你的意思是我在第一个原始方法中的逻辑似乎没问题吗?我确实注意到在我的应用程序的另一部分中,我使用&amp;&amp;|| 的条件语句也没有按预期工作,尽管在调试时一切似乎都很好。我知道很奇怪。所以现在我使用单个 &amp;| 运算符来看看当我的应用程序在市场上时这是否会有所作为。
    • 请注意,在引用 code.msdn.microsoft.com/… 时,它很好地描述了试用实现的工作原理以及 TrialViewModel.LicenseModeString 返回的内容。在 Visual Studio 的调试模式下,它将返回 TrialFull 以模拟真实的许可证状态,但在发布模式下,它返回 MissingOrRevoked,因为没有要查询的真实许可证状态。但是,一旦应用程序投放市场并且可以确定许可证,这个问题就会得到解决。
    • 确定一下,您正在发布应用的发布版本?
    • 当许可证状态为MissingOrRevoked 时,仅考虑释放模式下TrialViewModel.LicenseModeString 的值,所有条件都被跳过,方法内没有任何反应。一旦应用程序从市场下载并在我的设备上运行后,我无法知道这些值,但在视觉上发生了完全相同的行为。
    • 是的,是的,我一定是在写我之前的评论,就像你发送你的评论一样。
    猜你喜欢
    • 2019-08-26
    • 2016-04-14
    • 2013-06-02
    • 2020-07-22
    • 1970-01-01
    • 2010-11-08
    • 2021-10-03
    • 2012-12-16
    相关资源
    最近更新 更多