简体   繁体   English

无法为WP 8.1中的隐式类型的局部变量分配void

[英]Cannot assign void to an implicitly-typed local variable in WP 8.1

I am developing a music player app in WP 8.1 & I am trying to implement Jump List feature into it. 我正在WP 8.1中开发音乐播放器应用,并且正在尝试将Jump List功能实现到其中。 To implement jump list, I am following the sample given here . 为了实现跳转列表,我将遵循此处给出的示例。

I am making some necessary changes to the available code & that's how I am implementing the desired feature as my knowledge in C#, MVVM & WP 8.1 is minimal. 我正在对可用代码进行一些必要的更改,这就是我实现所需功能的方式,因为我对C#,MVVM和WP 8.1的了解很少。

But I am facing an error in my ViewModel at line 但是我在ViewModel中遇到错误

var items = ContactModel.CreateSampleData();

and the error is: 错误是:

Cannot assign void to an implicitly-typed local variable

What could be the possible reason???? 可能是什么原因???? Can anyone help me understand where I went wrong. 谁能帮助我了解我哪里出了问题。

using System.Collections;
using Windows.UI.Xaml.Data;
using JumpListSample.Common.JumpList;
using System.Collections.Generic;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using System;
using Windows.Storage;
using Windows.Storage.Search;
using System.Collections.ObjectModel;

namespace JumpListSample.ViewModels
{
    public class ContactsViewModel
    {
        private IList data;
        public IList Data
        {
            get
            {
                if (data == null)
                {
                    var items = ContactModel.CreateSampleData();
                    data = items.ToAlphaGroups(x => x.Name);
                }
                return data;
            }
        }
        private CollectionViewSource collection;

        public CollectionViewSource Collection
        {
            get
            {
                if (collection == null)
                {
                    collection = new CollectionViewSource();
                    collection.Source = Data;
                    collection.IsSourceGrouped = true;
                }
                return collection;
            }
        }
    }

    public class ContactModel
    {
        // constructor
        public ContactModel()
        {
            Name = "name";
            Albumart = new BitmapImage(new Uri("ms-appx:///Assets/Logo.scale-240.png"));
        }

        public async  static void CreateSampleData()
        {
            ObservableCollection<ContactModel> data = new ObservableCollection<ContactModel>();

            try
            {
                IReadOnlyList<IStorageItem> MusicLibrary = await KnownFolders.MusicLibrary.GetFoldersAsync(CommonFolderQuery.GroupByAlbum);
                foreach (IStorageItem item in MusicLibrary)
                {
                    ContactModel obj = new ContactModel();
                    IStorageItem musicItem = item;
                    obj.Name = musicItem.Name;
                    obj.Albumart = new BitmapImage(new Uri("ms-appx:///Assets/Logo.scale-240.png"));
                    data.Add(obj);
                }
            }
            catch
            {
            }
            finally
            {
            } 
        }

        public string Name { get; set; }
        public ImageSource Albumart { get; set; }
    }
}

Demo code can be downloaded from here . 演示代码可从此处下载。

I concur with commenter Clint Good's suggestion. 我同意评论员克林特·古德的建议。 Your CreateSampleData() method appears to be responsible for initializing a collection of ContactModel instances. 您的CreateSampleData()方法似乎负责初始化ContactModel实例的集合。 Presumably, you are calling this from the Data property because these are the items you want to use to initialize the data field. 大概是从Data属性调用此函数,因为这是您要用来初始化data字段的项。

That said, you have a serious problem: C# properties do not support the async / await pattern. 就是说,您遇到了一个严重的问题:C#属性不支持async / await模式。 One idiom for addressing this is to asynchronously initialize the backing field, and then raise a property-changed event when the initialization has completed. 解决这个问题的一个惯用法是异步初始化背景字段,然后在初始化完成后引发属性更改的事件。 Unfortunately, your ContactsViewModel class does not implement INotifyPropertyChanged or inherit DependencyObject (the two ways XAML-based programs handle property-change notification). 不幸的是,您的ContactsViewModel类没有实现INotifyPropertyChanged或继承DependencyObject (基于XAML的程序处理属性更改通知的两种方式)。

Taking all that together and making the necessary changes to your code, you'd wind up with something like this: 综合所有这些并对代码进行必要的更改,您将得到如下所示的结果:

ContactsViewModel: ContactsViewModel:

public class ContactsViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    private IList data;
    public IList Data
    {
        get
        {
            if (data == null)
            {
                // Ignore the returned Task...we're not going to do anything with it
                var _ = InitData();
            }

            // Caller should handle null. If not, need to return "new Data[0]" here instead
            return data;
        }
    }

    private async Task InitData()
    {
        // Catch _specific_ exceptions here, if necessary

        var items = await ContactModel.CreateSampleData();
        data = items.ToAlphaGroups(x => x.Name);
        OnPropertyChanged("Data");
    }

    private CollectionViewSource collection;

    public CollectionViewSource Collection
    {
        get
        {
            if (collection == null)
            {
                collection = new CollectionViewSource();
                collection.Source = Data;
                collection.IsSourceGrouped = true;
            }
            return collection;
        }
    }
}

ContactModel: 联系人型号:

public class ContactModel
{
    // constructor
    public ContactModel()
    {
        Name = "name";
        Albumart = new BitmapImage(new Uri("ms-appx:///Assets/Logo.scale-240.png"));
    }

    public async static Task<ObservableCollection<ContactModel>> CreateSampleData()
    {
        ObservableCollection<ContactModel> data = new ObservableCollection<ContactModel>();

        IReadOnlyList<IStorageItem> MusicLibrary = await KnownFolders.MusicLibrary.GetFoldersAsync(CommonFolderQuery.GroupByAlbum);
        foreach (IStorageItem item in MusicLibrary)
        {
            ContactModel obj = new ContactModel();
            IStorageItem musicItem = item;
            obj.Name = musicItem.Name;
            obj.Albumart = new BitmapImage(new Uri("ms-appx:///Assets/Logo.scale-240.png"));
            data.Add(obj);
        }

        return data;
    }

    public string Name { get; set; }
    public ImageSource Albumart { get; set; }
}

Note that I have also removed your try/catch entirely. 请注意,我也完全删除了您的try / catch。 It is very bad to simply swallow exceptions. 简单地吞下异常非常不好。 If you think you need to handle any exceptions, handle them in the caller (ie ContactsViewModel.InitData() ) where you can do something useful and notify the user if necessary (but only handle specific exceptions, ones you know how to respond to). 如果您认为需要处理任何异常,请在调用方中处理它们(即ContactsViewModel.InitData() ),在其中您可以做一些有用的事情,并在必要时通知用户(但仅处理特定的异常,您知道如何响应) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM