কোনও ফিল্ড ইনিশিয়ালাইজার ননস্ট্যাটিক ক্ষেত্র, পদ্ধতি বা সম্পত্তি উল্লেখ করতে পারে না


96

আমার একটি ক্লাস রয়েছে এবং আমি অন্য ক্লাসে এটি ব্যবহার করার চেষ্টা করার সময় আমি নীচের ত্রুটিটি পেয়েছি।

using System;
using System.Collections.Generic;
using System.Linq;

namespace MySite
{
    public class Reminders
    {
        public Dictionary<TimeSpan, string> TimeSpanText { get; set; }

        // We are setting the default values using the Costructor
        public Reminders()
        {
            TimeSpanText.Add(TimeSpan.Zero, "None");
            TimeSpanText.Add(new TimeSpan(0, 0, 5, 0), "5 minutes before");
            TimeSpanText.Add(new TimeSpan(0, 0, 15, 0), "15 minutes before");
            TimeSpanText.Add(new TimeSpan(0, 0, 30, 0), "30 minutes before");
            TimeSpanText.Add(new TimeSpan(0, 1, 0, 0), "1 hour before");
            TimeSpanText.Add(new TimeSpan(0, 2, 0, 0), "2 hours before");
            TimeSpanText.Add(new TimeSpan(1, 0, 0, 0), "1 day before");
            TimeSpanText.Add(new TimeSpan(2, 0, 0, 0), "2 day before");
        }

    }
}

ক্লাসটি অন্য ক্লাসে ব্যবহার করা

class SomeOtherClass
{  
    private Reminders reminder = new Reminders();
    // error happens on this line:
    private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 
    ....

ত্রুটি (CS0236):

A field initializer cannot reference the nonstatic field, method, or property

কেন এটি ঘটে এবং কীভাবে এটি ঠিক করা যায়?

উত্তর:


147

এই লাইন:

private dynamic defaultReminder = 
                          reminder.TimeSpanText[TimeSpan.FromMinutes(15)];

অন্য উদাহরণ ভেরিয়েবলটি আরম্ভ করার জন্য আপনি কোনও উদাহরণ ভেরিয়েবল ব্যবহার করতে পারবেন না । কেন? কারণ সংকলক এগুলি পুনঃব্যবস্থা করতে পারে - এমন কোনও গ্যারান্টি নেই যা reminderআগে শুরু করা হবে defaultReminder, সুতরাং উপরের লাইনটি একটি নিক্ষেপ করতে পারেNullReferenceException ।

পরিবর্তে, কেবল ব্যবহার করুন:

private dynamic defaultReminder = TimeSpan.FromMinutes(15);

বিকল্পভাবে, নির্মাতায় মান সেট আপ করুন:

private dynamic defaultReminder;

public Reminders()
{
    defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 
}

এমএসডিএন - এই সংকলক ত্রুটি সম্পর্কে আরও বিশদ রয়েছে - সংকলক ত্রুটি CS0236 ।


4
জাভা এই ধরনের নির্মাণের জন্য আরও 'ক্ষমাশীল'। জানি না যে এটি ভাল জিনিস কিনা। stackoverflow.com/questions/1494735/…
— ওয়াউটার শুট

32
না, সংকলক আরম্ভকারীদের পুনর্বিন্যাস করতে পারে না। সি # ল্যাঙ্গুয়েজ স্পেসিফিকেশনটি "10.5.5.2 ইনস্ট্যান্স ফিল্ড ইনিশিয়ালাইজেশন" বিভাগের অধীনে নিম্নলিখিতটি উল্লেখ করেছে: চলক আরম্ভকারীরা পাঠ্যক্রম অনুসারে মৃত্যুদন্ড কার্যকর করা হয় যেখানে তারা শ্রেণীর ঘোষণায় উপস্থিত হয়। এটি এমনকি "10.11.2 ইনস্ট্যান্স ভেরিয়েবল ইনিশিয়েলাইজারস" -এ পুনরাবৃত্তি হয়েছে যেখানে তারা বলে: পরিবর্তনশীল ইনিশিয়েলাইজারগুলি পাঠ্য ক্রমে কার্যকর করা হয় যেখানে তারা শ্রেণির ঘোষণায় উপস্থিত হয়। সুতরাং আপনার ব্যাখ্যা ভুল। অর্ডার ঠিক করা হয়েছে। এটি অস্বীকার করার কারণ হ'ল সি # এর ডিজাইনাররা সেভাবে এটি চেয়েছিল।
— জেপ্প স্টিগ নীলসন

(কেবলমাত্র partial classবেশ কয়েকটি ফাইলে "পার্টস" যুক্ত ক্ষেত্রে ফিল্ড আরম্ভকারীদের ক্রমটি অস্পষ্ট, তবে এটি staticক্ষেত্রগুলিতেও যায় !)
— জেপ্প স্টিগ নিলসেন

@ ওয়াটারশুট আপনার থ্রেডটি সংযুক্ত থ্রেডটি জাভা সম্পর্কে নয় ?! এটি staticউদাহরণস্বরূপ ক্ষেত্রগুলির পরিবর্তে ক্ষেত্রগুলি সহ, তবে সি # সম্পর্কেও ।
— জেপ্প স্টিগ নীলসন

4
@ অ্যান্ড্রু মোটেও সত্য নয়, খারাপ অভ্যাসগুলি নিষিদ্ধ করার জন্য অনেকগুলি সিদ্ধান্ত নেওয়া হয়। যদিও তারা, তাত্ত্বিকভাবে প্রয়োগ করা যেতে পারে, কিছু সতর্কতা দ্বারা রক্ষিত হয় এবং কিছুগুলি সরল ত্রুটি। এবং আমি মনে করি যে এটি এর মধ্যে অন্যতম একটি ঘটনা ... যদিও মানকটি এটি ক্রমগত বলছে, এমনকি একজন অভিজ্ঞ বিকাশকারী এটি আত্মবিশ্বাসের সাথে বলতে পারবেন না (মানটি সন্ধান না করে)।
— টোমর ডাব্লু

22

আপনার কোডটি আপনার ক্লাসের কনস্ট্রাক্টরের মধ্যে রাখতে হবে:

private Reminders reminder = new Reminders();
private dynamic defaultReminder;

public YourClass()
{
    defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}

কারণটি হ'ল আপনি ফিল্ড ইনিশিয়ালাইজার ব্যবহার করে অন্য একটিকে আরম্ভ করার জন্য একটি উদাহরণ ভেরিয়েবল ব্যবহার করতে পারবেন না।


10

আপনি এই মত ব্যবহার করতে পারেন

private dynamic defaultReminder => reminder.TimeSpanText[TimeSpan.FromMinutes(15)]; 

11
স্ট্যাক ওভারফ্লোতে স্বাগতম! এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, যদিও সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না। আপনার কোডটি ব্যাখ্যামূলক মন্তব্যে ভিড় না করার চেষ্টা করুন, কারণ এটি কোড এবং ব্যাখ্যা উভয়ের পাঠযোগ্যতা হ্রাস করে!
— jmattheis

4
এটি = এর পরিবর্তে = ব্যবহার করে এটি একটি সম্পত্তি হিসাবে তৈরি করে।
— ভিনসেন্ট

4
এই কৌশলটি ব্যবহারে সতর্ক থাকুন, যেহেতু =>ব্যবহারটি আসল মান সেট করে না, তবে প্রতিবার defaultReminderঅ্যাক্সেস পাওয়া কোডটি কার্যকর করবে । এটি উদ্দেশ্যযুক্ত নাও হতে পারে এবং এর নেতিবাচক কর্মক্ষমতা প্রভাব ফেলতে পারে, বা জিসি ইত্যাদির জন্য অযাচিত চাপ তৈরি করতে পারে
— হাসিমুখী

4

private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];ফিল্ড ইনিশিয়ালাইজার এবং এটি প্রথম চালায় (ইনিশিয়ালাইজার ব্যতীত কোনও ক্ষেত্র তার ডিফল্ট মানতে সেট করার আগে এবং অনুরোধকৃত কনস্ট্রাক্টর মৃত্যুদন্ড কার্যকর করার আগে)। উদাহরণস্বরূপ ক্ষেত্রগুলিতে কোনও প্রারম্ভিক নেই এমন সমস্ত দৃষ্টিকোণ ক্ষেত্র আরম্ভকারী সম্পন্ন হওয়ার পরে কেবলমাত্র একটি আইনি (ডিফল্ট) মান থাকবে। প্রারম্ভিক ক্রমের কারণে, কনস্ট্রাক্টরগুলি সর্বশেষে মৃত্যুদন্ড কার্যকর করা হয়, এজন্য আরম্ভকারীগুলি কার্যকর করার মুহুর্তটি এখনও তৈরি হয়নি। সুতরাং সংকলক শ্রেণীর উদাহরণ সম্পূর্ণরূপে নির্মাণের আগে কোনও উদাহরণ সংস্থান (বা ক্ষেত্র) রেফারেন্স করতে দেয় না। এর কারণ হ'ল ইনস্ট্যান্স ভেরিয়েবলের মতো কোনও অ্যাক্সেস যেমন reminderস্পষ্টভাবে উল্লেখ করে উদাহরণটি ( this) সংকলকটি ব্যবহারের জন্য কংক্রিটের মেমরির অবস্থানটি বলতে।

thisউদাহরণস্বরূপ ফিল্ড ইনিশিয়ালাইজারে অনুমোদিত না হওয়ার কারণও এটি।

উদাহরণস্বরূপ ক্ষেত্রের জন্য একটি পরিবর্তনশীল ইনিশিয়ালাইজারটি তৈরি হওয়া ঘটনাকে উল্লেখ করতে পারে না। সুতরাং এটি ভেরিয়েবল ইনিশিয়ালাইজারে রেফারেন্স করা একটি সংকলন-সময় ত্রুটি, কারণ কোনও ভেরিয়েবল ইনিশিয়ালাইজারের জন্য কোনও সরল_নামের মাধ্যমে কোনও উদাহরণ সদস্যকে রেফারেন্স করার জন্য এটি একটি সংকলন-সময় ত্রুটি ।

উদাহরণস্বরূপ ক্ষেত্রের আরম্ভকারীদের মৃত্যুদন্ড কার্যকর করার আগে কেবলমাত্র টাইপ সদস্যদের শুরুর গ্যারান্টিযুক্ত তারা হলেন ক্লাস (স্ট্যাটিক) ফিল্ড ইনিশিয়ালাইজার এবং ক্লাস (স্ট্যাটিক) কনস্ট্রাক্টর এবং ক্লাস পদ্ধতি। স্থিতিশীল সদস্যরা যেমন স্বতন্ত্র, যেহেতু এগুলি যে কোনও সময় উল্লেখ করা যেতে পারে:

class SomeOtherClass
{
  private static Reminders reminder = new Reminders();

  // This operation is allowed,
  // since the compiler can guarantee that the referenced class member is already initialized
  // when this instance field initializer executes
  private dynamic defaultReminder = reminder.TimeSpanText[TimeSpan.FromMinutes(15)];
}

এই কারণেই ক্ষেত্রের প্রারম্ভিকদের কেবলমাত্র কোনও শ্রেণীর সদস্য (স্থির সদস্য) রেফারেন্স করার অনুমতি দেওয়া হয়। এই সংকলক প্রারম্ভিক বিধিগুলি একটি নির্মাতারা টাইপ ইনস্ট্যান্টেশন নিশ্চিত করবে।

আরও তথ্যের জন্য আমি এই দস্তাবেজটি সুপারিশ করছি: মাইক্রোসফ্ট ডক্স: শ্রেণির ঘোষণা ।

এর অর্থ হ'ল একটি উদাহরণ ক্ষেত্র যা অন্য উদাহরণ সদস্যকে এর মান শুরু করার জন্য রেফারেন্স করে, অবশ্যই ইনস্ট্রাক্টর থেকে আরম্ভ করতে হবে বা রেফারেন্স করা সদস্যকে অবশ্যই ঘোষণা করতে হবে static।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.