简体   繁体   中英

protected field is not accesible from derived class in C#

I tried to access a protected string from derived class, but its not accessible

public class ParentClass
    {
        public string UserName {
            get { return "User Name is accessible to any class under same namespace Skin_File"; }
            set { }
        }
        private string AccountNumber {
            get { return "Not accessible from child class"; }
            set { }
        }
        internal string UserAge {
            get { return "User Age is accesible to child class"; }
            set { }
        }
        protected string PhoneNumber {
            get { return "Accessible only to ParentClass"; }
            set { }
        }
    }
    protected class DerivedClass : ParentClass
    {
        string DerivedUserName = new ParentClass().UserName;
        string  DerivedAccountNumber = new ParentClass().AccountNumber; // Not accessible since that was private
        string DerivedUserAge = new ParentClass().UserAge;
        protected  string DerivedPhoneNumber = new ParentClass().PhoneNumber; // derived class but not accessible
    }

Here is the fiddle for people who need it.

This:

string DerivedPhoneNumber = new ParentClass().PhoneNumber;

Creates an instance of ParentClass from the and will only have access to public members. As you're inherting ParentClass , you inherit its protected members as well.

If you want to initialize the value, you need to do so inside your class constructor:

protected DerivedClass()
{
    DerivedPhoneNumber = PhoneNumber;
}

Although, I don't see the point in declaring another field to store the same number. Access it directly.

You create an instance of ParentClass. You can't see the protected members. You have access to it's protected members from the DerivedClass. You have to just invoke

protected  string DerivedPhoneNumber = PhoneNumber;

Try the following

internal class DerivedClass : ParentClass
{
    string DerivedUserName = new ParentClass().UserName;
    string DerivedUserAge = new ParentClass().UserAge;
    protected string DerivedPhoneNumber;// = PhoneNumber; // derived class but not accessible

    public DerivedClass() {
        DerivedPhoneNumber = PhoneNumber;
    }
}

You shouldn't create a new class for your so called access, it completely breaks the inheritance.

Private fields are only accessible from within the declaring class. Protected fields are accessible from declaring class + all derived classes + extension methods Internal fields are accessible from declaring class + all derived classes + extension methods within same namespace / assembly (i think)

Furthermore, when thinking about baseclasses/derived classes, think about the modifiers as well, properties/methods that you wish to allow to be modified by base classes should be marked virtual, properties/methods that shouldn't be further extended, should not get the modifiers.

so, baseclass:

public class ParentClass
{
    private string userName;
    public virtual string UserName
    {
        get
        {
            return username;
        }
        set
        {
            username = value;
        }
    }

    private string accountNumber; // don't see a reason why it should be a property rather than a field...

    private int userAge;
    internal int UserAge
    {
        get
        {
            return userAge;
        }
        set
        {
            userAge = value;
        }
    }

    protected string phoneNumber;
    public virtual string PhoneNumber
    {
        get
        {
            return phoneNumber;
        }
        set
        {
            phoneNumber = value;
        }
    }

    public ParentClass()
    {
        // potentially do something intresting
    }
}

now to make it polymorphic

public class DerivedClass : ParentClass
{
    public string CountryCode
    {
        get; set;
    }
    // we can override phoneNumber
    public override string PhoneNumber
    {
        get
        {
            if (!string.IsNullOrWhiteSpace(base.PhoneNumber)) {
                 return base.PhoneNumber;
            }
            if (!base.PhoneNumber.StartsWith(CountryCode)) {
                return CountryCode + base.PhoneNumber;
            }
            return base.PhoneNumber;  // you could also return the field phoneNumber instead (as it is protected)
        }
        set
        {
            base.PhoneNumber = CountryCode + value; // you could also set the field phoneNumber ... (we are adding country code here)
        }
    }

    public DerivedClass() : this("0049")
    {
    }

    public DerivedClass(string countryCode) : base() // call the base constructor as well
    {
        // do something more than what the parentclass is doing, eg...
         this.CountryCode = countryCode;
    }
}

Now, in the Derivedclass you could choose to set / return the phonenumber differently, this would mean that all classes that see the ParentClass, can also work with a DerivedClass, and with the same property, but the implementation of that property would be changed by the derived class.

However, your example really doesn't seem clear enough to me, to know what your request is, what you would like to do, and how it should behave.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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