无法访问外部类型的非静态成员..通过嵌套类型

本文关键字:静态成员 嵌套类型 访问 外部 类型 | 更新日期: 2023-09-27 18:19:54

为什么会出现此错误?

错误CS0038:无法访问外部类型的非静态成员JsonFeedParserTabs.MainActivity' via nested type JsonFeedParserTabs.MainActivity.SampleTabFragment(CS0038)(JsonFeedParserTabs)

我正在尝试将一个包含json数据的ListView放在一个选项卡中

这是我的代码:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using System.Linq;
namespace JsonFeedParserTabs
{
    [Activity (Label = "Feed Reader", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        ListView listView;
//      ProgressBar progressBar;
        RootObject result;
        string url = "http://javatechig.com/api/get_category_posts/?dev=1&slug=android";
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            // Set our view from the "main" layout resource.
            SetContentView (Resource.Layout.Main);
            this.ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;
            AddTab (" Tab 1", new SampleTabFragment ());
//          AddTab (" Tab 2", new SampleTabFragment2 ());
            if (bundle != null)
                this.ActionBar.SelectTab(this.ActionBar.GetTabAt(bundle.GetInt("tab")));
        }
        protected override void OnSaveInstanceState(Bundle outState)
        {
            outState.PutInt("tab", this.ActionBar.SelectedNavigationIndex);
            base.OnSaveInstanceState(outState);
        }
        void AddTab (string tabText, Fragment view)
        {
            var tab = this.ActionBar.NewTab ();
            tab.SetText (tabText);
            // Must set event handler before adding tab.
            tab.TabSelected += delegate(object sender, ActionBar.TabEventArgs e) {
                var fragment = this.FragmentManager.FindFragmentById(Resource.Id.fragmentContainer);
                if (fragment != null)
                    e.FragmentTransaction.Remove(fragment);
                e.FragmentTransaction.Add (Resource.Id.fragmentContainer, view);
            };
            tab.TabUnselected += delegate(object sender, ActionBar.TabEventArgs e) {
                e.FragmentTransaction.Remove(view);
            };
            this.ActionBar.AddTab (tab);
        }
        class SampleTabFragment : Fragment
        {
            public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                base.OnCreateView (inflater, container, savedInstanceState);
                var view = inflater.Inflate (Resource.Layout.Tab, container, false);
                // Initializing listView.
                listView = view.FindViewById<ListView> (Resource.Id.listView); // <-- Error!
                listView.ItemClick += OnListItemClick; // <-- Error!
//              progressBar = view.FindViewById<ProgressBar> (Resource.Id.progressBar);
//  
//              // Showing loading progressBar.
//              progressBar.Visibility = ViewStates.Visible;
                // Download and display data in url.
                downloadJsonFeedAsync (url); // <-- Error!
                return view;
            }
        }
//      class SampleTabFragment2 : Fragment
//      {
//          public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
//          {
//              base.OnCreateView(inflater, container, savedInstanceState);
//
//              var view = inflater.Inflate(Resource.Layout.Tab, container, false);
//              var sampleTextView = view.FindViewById<TextView>(Resource.Id.sampleTextView);
//
//              sampleTextView.Text = "Sample fragment text 2.";
//
//              return view;
//          }
//      }
        public async void downloadJsonFeedAsync(String url)
        {
            var httpClient = new HttpClient();
            Task<string> contentsTask = httpClient.GetStringAsync(url);
            // Await! control returns to the caller and the task continues to run on another thread.
            string content = await contentsTask;
            Console.Out.WriteLine("Response Body: 'r'n {0}", content);
            // Convert string to JSON object.
            result = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject> (content);
            // Update listview.
            RunOnUiThread (() => {
                listView.Adapter = new CustomListAdapter(this, result.posts);
//              progressBar.Visibility = ViewStates.Gone;
            });
        }
        void OnListItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            Post item = result.posts.ElementAt (e.Position);
            // Passing object form one activity to other.
            Intent i = new Intent(Application.Context, typeof(FeedDetailsActivity));
            i.PutExtra("item", JsonConvert.SerializeObject(item));
            StartActivity(i);
        }
    }
}

我被困了,需要帮助,你知道我做错了什么,该怎么办吗?非常感谢。

更新

好吧,它现在起作用了,但我认为可能有更好的方法来做到这一点。

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using System.Linq;
namespace JsonFeedParserTabs
{
    [Activity (Label = "Feed Reader", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        ListView listView;
//      ProgressBar progressBar;
        RootObject result;
        string url = "http://javatechig.com/api/get_category_posts/?dev=1&slug=android";
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            // Set our view from the "main" layout resource.
            SetContentView (Resource.Layout.Main);
            this.ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;
            AddTab (" Tab 1", new SampleTabFragment (this));
//          AddTab (" Tab 2", new SampleTabFragment2 ());
            if (bundle != null)
                this.ActionBar.SelectTab(this.ActionBar.GetTabAt(bundle.GetInt("tab")));
        }
        protected override void OnSaveInstanceState(Bundle outState)
        {
            outState.PutInt("tab", this.ActionBar.SelectedNavigationIndex);
            base.OnSaveInstanceState(outState);
        }
        void AddTab (string tabText, Fragment view)
        {
            var tab = this.ActionBar.NewTab ();
            tab.SetText (tabText);
            // Must set event handler before adding tab.
            tab.TabSelected += delegate(object sender, ActionBar.TabEventArgs e) {
                var fragment = this.FragmentManager.FindFragmentById(Resource.Id.fragmentContainer);
                if (fragment != null)
                    e.FragmentTransaction.Remove(fragment);
                e.FragmentTransaction.Add (Resource.Id.fragmentContainer, view);
            };
            tab.TabUnselected += delegate(object sender, ActionBar.TabEventArgs e) {
                e.FragmentTransaction.Remove(view);
            };
            this.ActionBar.AddTab (tab);
        }
        class SampleTabFragment : Fragment
        {
            private MainActivity context;
            public SampleTabFragment(MainActivity _context) : base()
            {
                this.context = _context;
            }
            public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                base.OnCreateView (inflater, container, savedInstanceState);
                var view = inflater.Inflate (Resource.Layout.Tab, container, false);
                // Initializing listView.
                context.listView = view.FindViewById<ListView> (Resource.Id.listView);
                context.listView.ItemClick += context.OnListItemClick;
//              progressBar = view.FindViewById<ProgressBar> (Resource.Id.progressBar);
//  
//              // Showing loading progressBar.
//              progressBar.Visibility = ViewStates.Visible;
                // Download and display data in url.
                context.downloadJsonFeedAsync (context.url);
                return view;
            }
        }
//      class SampleTabFragment2 : Fragment
//      {
//          public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
//          {
//              base.OnCreateView(inflater, container, savedInstanceState);
//
//              var view = inflater.Inflate(Resource.Layout.Tab, container, false);
//              var sampleTextView = view.FindViewById<TextView>(Resource.Id.sampleTextView);
//
//              sampleTextView.Text = "Sample fragment text 2.";
//
//              return view;
//          }
//      }
        public async void downloadJsonFeedAsync(String url)
        {
            var httpClient = new HttpClient();
            Task<string> contentsTask = httpClient.GetStringAsync(url);
            // Await! control returns to the caller and the task continues to run on another thread.
            string content = await contentsTask;
            Console.Out.WriteLine("Response Body: 'r'n {0}", content);
            // Convert string to JSON object.
            result = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject> (content);
            // Update listview.
            RunOnUiThread (() => {
                listView.Adapter = new CustomListAdapter(this, result.posts);
//              progressBar.Visibility = ViewStates.Gone;
            });
        }
        void OnListItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            Post item = result.posts.ElementAt (e.Position);
            // Passing object form one activity to other.
            Intent i = new Intent(Application.Context, typeof(FeedDetailsActivity));
            i.PutExtra("item", JsonConvert.SerializeObject(item));
            StartActivity(i);
        }
    }
}

无法访问外部类型的非静态成员..通过嵌套类型

它告诉你它不能做什么。MainActivity成员不能从MainActivity类型中声明的片段类型访问。因此,当您尝试调用downloadJsonFeedAsync (url);时,它会失败,因为它不是一个静态(类)方法。片段(虽然在类型中声明)不存在于MainActivity类型的实例中。

除非有一些令人信服的理由让他们留在MainActivity类型中,否则我会把他们搬出去。然后,它们还应该有一个对MainActivity类型的引用,以便您可以对其调用downloadJsonFeedAsync(string)

关于一个无关的注释(我很感激这是非常不请自来的评论:),您可能需要考虑使用MVVM模式。看起来您将演示、应用程序控制和业务数据混合在一起。如果这个应用程序超出了一两个页面,你会发现在隔离责任方面很平静。