【问题标题】:passing null parameters传递空参数
【发布时间】:2012-05-07 06:06:16
【问题描述】:

我目前在解决这个问题时遇到了一些麻烦。我有一个不需要任何参数的方法,现在我需要添加一个参数,但我不想在调用该方法的所有不同位置添加参数。这是我目前的方法:

private IEnumerable<SearchItems> GetItems(ItemDescriptionFormViewModel viewModel = null)
    {
        IOrderedQueryable<ItemDescription> items= _itemDescriptionRepository.FindAll().OrderBy(
            c => c.Sort == null).ThenBy(
                c => c.Sort).ThenBy(c => c.Description);

        if(items.Count()==0)
            ModelState.AddModelError("", string.Format("No active {0} entered.", Kids.Resources.Entities.ItemDescription.EntityNamePlural));
       return
            _itemDescriptionRepository.FindAll().OrderBy(c => c.Description).Where(a=>a.IsActive == true || viewModel == null || a.ItemDescriptionId == viewModel.ItemDescriptionId).Select(
                c => new SearchItems {Text = c.Description, Value = c.ItemDescriptionId.ToString()});
    }

我尝试将 null 作为参数传递给正在调用此方法的其他地方,但出现错误。有什么办法让这个问题超载?

目的:添加 viewModel 的目的是因为我有一个下拉列表,其中包含可供选择的活动项目。一旦用户选择了一个活动项目,然后由于某种原因该项目变得不活动,用户就去编辑他们的选择。在下拉列表中应该有活动项目的列表以及它们之前选择的现在不活动的项目。我正在使用 ViewModel 来检查先前选择的项目的 id。

谢谢

【问题讨论】:

  • @Amina: null 是 viewModel 参数的有效值吗?
  • @Dennis 我有这样的参数:ItemDescriptionFormViewModel viewModel = null。
  • ItemDescriptionFormViewModel 是类还是结构?
  • @JamesMichaelHare ItemDescriptionFormViewModel 是一个类...我目前正在测试建议的更改。

标签: c# asp.net-mvc parameter-passing


【解决方案1】:

大家...感谢您在尝试解决此问题时提供的所有帮助和努力。我终于能够解决它,这是我解决问题的人:Checking List Item Id

【讨论】:

    【解决方案2】:

    你可以给viewModel分配一个默认值:

    private IEnumerable<SearchItems> GetItems(
        ItemDescriptionFormViewModel viewModel = null)
    {
        if (viewModel == null) 
            viewModel = new ItemDescriptionFormViewModel();
    

    这样,如果您只是调用GetItems(),它会将viewModel 视为new ItemDescriptionFormViewModel()

    【讨论】:

    • 当我尝试这个时,我得到了这个错误:'viewModel' 的默认参数值必须是编译时常量
    • 所以我认为你必须使用默认值 ItemDescriptionFormViewModel viewModel = null 并在比较值时测试 null 情况。
    • 我按照其他人的建议做了,但现在我得到的对象引用未设置为对象错误的实例。
    • :D 错误信息消失了,但我没有得到我想要的结果。拥有 ViewModel 的整个想法是检查先前选定项目的 id,并在编辑页面上将填充选定项目,但目前它没有显示该选定项目,因为我在选择它后使其处于非活动状态。目的是一旦用户选择一个项目,然后该项目变为非活动状态,当用户去编辑该项目时,它会在下拉列表中显示活动项目以及他之前选择的非活动项目。
    • 我认为你没有得到正确结果的原因是因为你创建了一个new ItemDescriptionFormViewModel(),所以ItemDescriptionID默认设置为0。您需要先检查ItemDescriptionID == 0,然后再检查 ID 以执行方法,就好像没有参数一样。
    【解决方案3】:

    这样声明:

    private IEnumerable<SearchItems> GetItems(ItemDescriptionFormViewModel viewModel = null) 
    

    并确保在您的方法中检查null,如下所示:

    return
            _itemDescriptionRepository.FindAll().OrderBy(c => c.Description).Where(a=> viewModel == null || (a.IsActive == true || a.ItemDescriptionId == viewModel.ItemDescriptionId)).Select(
                c => new SearchItems {Text = c.Description, Value = c.ItemDescriptionId.ToString()});
    

    这将允许您使用GetItems()GetItems(ItemDescriptionFormViewModel viewModel) 调用方法

    编辑:无视?因为 ItemDescriptionFormViewModel 是一个类

    【讨论】:

    • 当我尝试这个时,我得到一个对象引用未设置为对象错误的实例。它指的是我的 .cshtml 视图页面。
    • 你在什么对象上得到这个错误?你在方法的其他地方使用 viewModel 吗?
    • 确切的行是:self.items = @Html.Raw(Json.Encode(Mode.Items));在我目前唯一一次使用 viewModel 的方法中,只是检查我当前在代码中拥有的项目的 Id。
    • 如果你只用它来查找一个ID,你可以只传递一个int而不是整个viewModel。另外,您是否进行了空检查?不带参数调用它是必不可少的。
    【解决方案4】:

    您在此处取消引用空引用:

    _itemDescriptionRepository.FindAll()
        .OrderBy(c => c.Description)
        .Where(a=>a.IsActive == true || 
            a.ItemDescriptionId == viewModel.ItemDescriptionId) // if viewModel null, this throws
        .Select(c => new SearchItems 
        {
            Text = c.Description, Value = c.ItemDescriptionId.ToString()
        });
    

    因此,如果视图模型为空,您只需更新您的 Where() 子句以添加 pass:

    ...
    .Where(a => a.IsActive || viewModel == null || viewModel.ItemDescriptionId == a.ItemDescriptionId)
    

    然后你可以安全地传递null作为参数,你甚至可以设置一个默认参数值,所以如果没有传递参数,它假定null

    当然,这是假设 ItemDescriptionFormViewModel 是一个类,如果它是一个结构,那么你必须使它可以为空 ItemDescriptionFormViewModel?

    【讨论】:

    • 当我调整代码时,我的 .cshtml 视图页面上的对象引用未设置为对象错误的实例。
    • @Amina:在哪一行?那是您使用 viewModel 的唯一地方。你能用最新的代码更新你的问题吗?
    • 我将我的代码更新为我所拥有的。确切的错误行在我的视图页面中: self.items = @Html.Raw(Json.Encode(Model.Items));以及我在之前的评论中提到的错误消息。我对这个错误有些困惑。显示我的 viewModel 会有帮助吗?非常感谢您的帮助 - 谢谢。
    【解决方案5】:

    如果你想保留这两个方法(我的意思是 GetItems() 和 GetItems(viewModel)),它们会自动重载。

    如果你想要第二种方法,你可以像这样传递参数

     private IEnumerable<SearchItems> GetItems(ItemDescriptionFormViewModel? viewModel)
    

    现在您可以将 null 作为其参数传递。

    【讨论】:

    • 仅当ItemDescriptionFormViewModel 是值类型,即结构体时。此外,您需要记住检查viewModel.HasValue,如果返回true,您可以使用viewModel.Value 访问它的值。
    • 这对我不起作用,因为 ItemDescriptionFormViewModel 是一个类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2015-03-09
    • 2018-05-15
    相关资源
    最近更新 更多