Why does FxCop treat protected members as if they are public throwing DoNotDeclareVisibleInstanceFields error? I'm pretty sure protected members is a valid code design.
It's telling you not to declare fields which are visible outside the class, i.e. not private. In this case it is correctly recognising the protected modifier as exposing the members outside the class, albeit only to derived types.
I'm not sure if that's what you meant, but in general protected members are part of a class' interface.
You don't want public member variables because they make your implementation inflexible. Protected member variables do the same since classes that inherit from yours will depend on them, thus making your implementation inflexible.
Asaf
It looks like the error you're getting is flagging your externally visible instance fields. The recommended practice here is to make this field private and expose it through an externally visible property (with a public or protected access modifier).
The MSDN page on the error gives a good example:
using System;
namespace DesignLibrary
{
public class BadPublicInstanceFields
{
// Violates rule DoNotDeclareVisibleInstanceFields.
public int instanceData = 32;
}
public class GoodPublicInstanceFields
{
private int instanceData = 32;
public int InstanceData
{
get { return instanceData; }
set { instanceData = value ; }
}
}
}
Related
is this possible to create a private members in interface in .NET? I heard that it is possible now but I my IDE is rejecting it:
public interface IAnimal
{
void SetDefaultName(string name)
{
ChangeName(name);
}
private string defaultName = "NoName";
private void ChangeName(string name)
{
defaultName = name;
}
void Breath()
{
Console.WriteLine($"Default - I'm {defaultName}. <Breathing sounds>");
}
void Sound();
}
Yes! Now you can in C# 8.0 but it has to be a static member. Like this:
public interface IAnimal
{
static void SetDefaultName(string name)
{
ChangeName(name);
}
private static string defaultName = "NoName";
private static void ChangeName(string name)
{
defaultName = name;
}
void Breath()
{
Console.WriteLine($"Default - I'm {defaultName}. <Breathing sounds>");
}
void Sound();
}
But you need to keep in mind that static fields will be shared across the application. Changing the defaultName will result in changing it in every place where you are using IAnimal
private methods used to be prohibited in interfaces because interfaces are supposed to be contracts. They are a guarantee that "this class has the following methods and properties". Why would it be useful to guarantee that a class has a private method? It isn't useful, because no one else can call it!
In C# 8, this changed. You can now specify private interface default methods. Note that it has to be a default method, not the ones that doesn't have an implementation. Here's the docs stating that fact:
The syntax for an interface is relaxed to permit modifiers on its members. The following are permitted: private, protected, internal, public, virtual, abstract, sealed, static, extern, and partial.
...
It is an error for a private or sealed function member of an interface to have no body.
Here is a quote from the docs explaining why this is allowed:
Static and private methods permit useful refactoring and organization of code used to implement the interface's public API.
The actual question should be : should i do (or be able to do) it or not ?
The whole idea of the interface thing is to provide abstraction .
private members usually are implementation details that the consumer of your code shouldn't care about or know they exists so they don't belong to your abstract layer (interface)
the interface is the facade that the consumer will interact with ur service/component thorough , it should contain only the methods that the consumer will call , this is why originally interfaces should have only public modifiers
not to mention that putting such members in the interface will force every implementation of it to implement these members even if they don't need it
from my opinion the only reason C# changed interfaces and made them allow implementation is to make up for the language lack of support for multiple class inheritance , but that does mean that you should miss use ur interfaces like that
Yes, with C# 8.0, you can have public, private and protected members.
For example, following works:
public interface ITest
{
private SomeEnum EnumTy { get => SomeEnum.Value1; }
}
If a class implements an interface and tries to access the variable, they will get an error.
public class TestImpl : ITest
{
ITest.EnumTy = SomeEnum.Value2; // gives an error
}
The members can also be protected. As a suggestion, going forward its good to have public before methods to indicate more readability (even though public is default).
A good article is here:
https://jeremybytes.blogspot.com/2019/11/c-8-interfaces-public-private-and.html
I understand that a private protection level is meant to stop any child accessing private parent variables.
But isn't there a way to do it with accessors and mutators(get and set)? I have to have some kind of way to change a private string because that is the homework.
I have a public abstract pet class with a private string for a name. I want to create a dog and use that string name. I can't figure it out though. Since it is homework, I understand I cannot be given code or anything, but could someone point out the method to do this so I can google it? All my searches just imply that it is impossible.
Here's my code if it will help.
edit
I can't just make it protected.
public abstract class Pet
{
private string name;
private string species;
public abstract void speak();
public abstract void play();
public abstract void info();
}
Part of the child dog class...
class Dog : Pet
{
public Dog(string xname, string xspecies)
{
this.name = xname; // this is where I'm having trouble.
}
Let's make sure that you have a clear and accurate understanding; many beginners are taught subtle falsehoods.
I understand that a private protection level is meant to stop any child accessing private parent variables.
That's a correct summary of the intention of the feature. Basically you are saying that access control modifiers are for controlling access, which should not be a surprise.
However there are two subtleties that I want to point out here.
The first is that access modifiers control access to the names of things, not to the things. When you have a member named foo, the name foo may only be used to refer to that member from within the accessibility domain of that member. The "accessibility domain" is a region of program text; the accessibility domain of a private member is the text of the type which declares the member.
If you have come up with some other way to refer to a member, that mechanism is not controlled by the accessibility modifier. The only thing an accessibility modifier controls is where the name may be used in the text of the program.
Make sure that is clear in your head.
Second, you note that a private member is not accessible to a "child", by which I assume you mean a derived class. There is a situation in which a derived class can access private member by name. Given what I've said so far, you should be able to deduce what it is. Give it some thought and then read on.
I said that a private member is accessible by name only inside the text of the declaring type, so if a private member is accessible by name by a derived class, the derived class must be inside the text of the declaring type:
class Base
{
private static int x;
class Derived : Base
{
static void M() { Console.WriteLine(Base.x); }
}
}
This is legal because x is used by name inside its accessibility domain.
So, how do you do your homework problem? There are only two ways:
(1) Put Dog inside of Pet; any Dog then has access to all the private members of Pet. This is a "for advanced players only" feature of C# and almost certainly not what your instructor is looking for. But it is a really powerful technique and I use it frequently, so keep it in mind for your later career; in particular, when you learn about the "factory pattern" you can pull out of your back pocket the knowledge that putting the derived classes inside the base class is a good trick for making the factory pattern work well.
(2) Make some accessor mechanism for the private member, and make that accessor mechanism's name protected, internal, or public.
Typically you'd use a property. You make an property with a read-only accessor in C# like this:
class Base
{
private int x;
public int X { get { return x; } }
}
Or, in more modern versions of C# you can use this short form:
public int X => x;
And now code outside of Base cannot use x by name, because that is outside of the accessibility domain of Base.x. But X has an unrestricted accessibility domain, so it can be used anywhere you like.
That's a read-only accessor. To make a write accessor you add a setter:
public int X
{
get { return x; }
set { x = value; }
}
Notice that setters have a magic value name that is the value that is to be assigned to the property.
There are other ways to make accessors but this is by far the most common.
While we are looking at your code, a couple other things:
(1)
public abstract void speak();
public abstract void play();
public abstract void info();
Public methods should be PascalCasedLikeThis, not lowercase, in C#. It's just an arbitrary convention that makes it easier to read your code.
(2)
Why is info void returning? Surely it should be returning some info.
(3)
class Dog : Pet
Is your intention to further subclass Dog? Probably not, because it is not abstract. Consider marking classes not intended to be subclassed as sealed, so that you do not have to worry about designing the class for safe inheritance.
I think you're looking for the protected access modifier, which means the variable is accessible within its class and by derived class instances:
public abstract class Pet
{
protected string name;
protected string species;
public abstract void Speak();
public abstract void Play();
public abstract void Info();
}
class Dog : Pet
{
public Dog(string xname, string xspecies)
{
name = xname;
species = xspecies;
}
// Implementation of Pet here
}
I was trying few things and would like to know why this is happening so.
Say, I have a class called A in namespace n and I was trying to create protected internal class B.
namespace n
{
public class A
{
public A()
{
}
}
protected internal class B //throwing error
{
}
}
But when i try like this (B as a sub class of A), its not throwing error and its built success. Could you explain me why it is so?
namespace n
{
public class A
{
public A()
{
}
protected internal class B // its not throwing error
{
}
}
}
Am i missing anything theoretically? Its quite a bit confusing.
A class can't be protected except when it is inside another class.
The protected keyword is only valid for members of a class. In your second example, class B happens to be that member.
Think about it:
protected means: Derived classes can access this member.
As there is no such concept as derived namespaces, the protected keyword doesn't make sense for members of a namespace.
Look at the error.
Elements defined in a namespace cannot be explicitly declared as
private, protected, or protected internal
Only internal or public members are allowed outside the class.
Your second case is defining the class B as member of class A that is why you are not getting the error.
You may see Access Modifiers C#
Classes and structs that are declared directly within a namespace (in
other words, that are not nested within other classes or structs) can
be either public or internal. Internal is the default if no access
modifier is specified.
protected declares visiblity level for derived types.
In your first case you declare class inside namespace. There is no any polymophic support for namespaces, so there is no any sence of using protected classes in namespace
In second case, instead, you use it inside other classe (class A), which make it visible for all children of A class.
I see a lot of code uses automatically generated property like {get; private set;} or {get; protected set;}.
What's the advantage of this private or protected set?
I tried this code, but it's the same when I have Foo{get; set;}.
public class MyClass
{
public int Foo {get; private set;}
public static void RunSnippet()
{
var x = new MyClass();
x.Foo = 30;
Console.WriteLine(x.Foo);
}
...
}
It makes a property read-only by external sources (i.e. classes that aren't MyClass and/or its subclasses). Or if you declared the property protected with a private set, it's read-only by its subclasses but writable by itself.
It doesn't make a difference in your class because your setter is private to that class, so your class can still access it. However if you tried to instantiate MyClass from another class, you wouldn't be able to modify the Foo property's value if it had a private or protected setter.
private and protected mean the same here as they do elsewhere: private restricts access only to that very class, while protected restricts access to that class and all its derived classes.
It makes a difference when you have a class model that uses inheritance. If your MyClass methods are clients of your private fields and methods it makes no difference.
That said, even if you don't anticipate your MyClass becoming a parent class in any sort of class hierarchy, it doesn't hurt to limit your field and method scope to the least visible scope that it requires. Encapsulate what you can with the least visible scope by default so that you don't have to refactor when subclasses start to access parent properties that they shouldn't be. The level of effort isn't any different from not doing so.
If you specify no access modifiers on the get and set keywords, the property will be accessible according to the access modifier of the property itself. In your example, you would be able to get the value of Foo and set the value of Foo from anywhere in your program if you specify get instead of private get.
In order to write robust code, you should try to always choose the most restrictive access modifier possible. It is a good idea to use properties to expose the state of your object, but not to change the state of your object from outside. If you want to change the state of your object, use method calls instead.
Think of the get and set functions in terms of accessor and mutator methods (except that you don't have to explicitly write the method bodies out:
private int foo;
public int get_Foo()
{
return foo;
}
public /* or protected, or private */ void set_Foo(int value)
{
foo = value;
}
After you see it like that, know that the protected and private modifiers work the same on a setter as they do on any other sort of member.
I've run into a compiler error that doesn't quite make sense to me. I have an internal property and I want to restrict its set block such that it is only available through inheritance. I thought this would work:
internal bool MyProperty {
get { return someValue; }
protected internal set { someValue = value; }
}
But the compiler says that the access modifier on the set block needs to be more restrictive than internal - am I missing something, or is protected internal not more restrictive than internal?
protected internal is less restrictive; it is protected or internal (not and) - which therefore additionally allows subclasses from other assemblies to access it. You would need to invert:
protected internal bool MyProperty {
get { return someValue; }
internal set { someValue = value; }
}
This will allow code in your assembly, plus subclasses from other assemblies, get it (read) - but only code in your assembly can set it (write).
From the documentation on Access Modifiers in C#:
The protected internal accessibility
level means protected OR internal, not
protected AND internal. In other
words, a protected internal member can
be accessed from any class in the same
assembly, including derived classes.
To limit accessibility to only derived
classes in the same assembly, declare
the class itself internal, and declare
its members as protected.
To achieve the desired effect, you instead need to swap the access modifiers, like so:
protected internal bool MyProperty
{
get { return someValue; }
internal set { someValue = value; }
}
No, it's the union of the two, not the intersection; hence protected internal is less restrictive than both of those individually. The intersection isn't a feature of C#; the CLR does support "Family AND Assembly", but C# only supports "Family OR Assembly".
Here, protected internal is less restrictive that internal.
protected internal - public for current assembly and any type that inherits this type in other assemblies.
internal - public for this assembly and private for other assemblies