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
}
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 am currently working on the chatbot for the Twitch channel and would like to have all the commands to be separate classes in the program so that I will only need to add or remove a single class to add or remove command.
I've searched through the Internet for quite long but never came across the suitable design. Below is what I think it has to look like but can't find the proper syntax.
class Command()
{
string keyword;
int globalCooldown;
List<string> args;
}
class DoStuffA : Command(List<string> _args)
{
keyword = "pleasedostuffa";
globalCooldown = 2;
args = _args;
DoStuff(List<string> args)
{
//doing stuff A here with all the logic and so on
}
}
class DoStuffB : Command(List<string> _args)
{
keyword = "pleasedostuffb";
globalCooldown = 8;
args = _args;
DoStuff(List<string> args)
{
//doing stuff B here with all the logic and so on
}
}
Why do I need this is because I want to store all possible commands in the List<Commands> and when the new chat message appears, search which object of this list matches the keyword with the chat command and execute the appropriate function. For example, if someone posts !pleasedostuffa, I perform
foreach (Command c in commands)//commands is List<Command>
{
if(c.keyword==receivedCommand.command)//.command is string
{
c.DoStuff(receivedCommand.argsAsList)//.argsAsList is List<string>
}
}
I hope I explained this properly and really am eager to have at least a clue on how could this implemented.
Thank you in advance!
You have the method setup almost right, though there are a few other changes you need. You need to have the base class expose DoStuff() as a virtual method. Try this:
public abstract class Command
{
public string keyword;
public int globalCooldown;
//List<string> args;
public abstract void DoStuff(List<string> args);
}
public class DoStuffA : Command
{
//public string keyword = "pleasedostuffa";
//public int globalCooldown = 2;
//args = _args;
public DoStuffA()
{
keyword = "pleasedostuffa";
globalCooldown = 2;
}
public override void DoStuff(List<string> args)
{
//doing stuff A here with all the logic and so on
}
}
public class DoStuffB : Command
{
//public string keyword = "pleasedostuffb";
//public int globalCooldown = 8;
// args = _args;
public DoStuffB()
{
keyword = "pleasedostuffb";
globalCooldown = 8;
}
public override void DoStuff(List<string> args)
{
//doing stuff B here with all the logic and so on
}
}
So, a couple of notes.
Method inheritance
Here I make the base class abstract, simply to enforce that each and every child command implements the abstract function DoStuff(). After all, what would you do with an instance of the base class? It wouldn't do anything, because you don't have an actual implementation. So abstract helps both to avoid accidentally instantiating Command itself and also makes sure sub-type implementers do the right thing.
Second, at the child class level, you need to override the method on the base class. This ensures that anything calling ((Command)doStuffB).DoStuff() gets the proper implementation of the function.
Now that you have a DoStuff() method on Command, your foreach loop should work as you expect. You have the method available on the base class, so the virtual overrides at the child level can be run without casting.
Base class member access
The fields you are trying to declare here, keyword and globalCooldown, aren't how people would typically expose information like this, but before we get to that I'm going to explain the more fundamental principle of accessing base-class members from the inherited classes.
These two fields need to be marked public (and given a proper type) so that they can be used from outside the class (in your foreach). The public keyword is called an accessibility modifier, and there are a few other options for accessibility, but in your case only public is likely to do what you want.
As you can see, I've commented out the fields in the child classes. If you declare them there, they will hide (but not override) the members of the same name on the base class. There's no equivalent of virtual or abstract for fields, so you need another strategy. Here, we leave your original declaration of those fields on the base class so that they are available to anything holding any type of a Command. But instead of redeclaring them at the child class level, we simply set the values of the base class members in the constructor for the child classes.
Note that for clarity's sake, you could explicitly specify that you are setting a member on the base class by using base.keyword = "etc"; instead.
Exposing internal values via properties
As I noted, this will work, but it's not quite how most people would expose the keyword and globalCooldown values. For this, you'd typically use a property instead. This lets you store and expose the values without risking letting someone change the value (intentionally or unintentionally). In this case, you'd want to declare the property this way:
public string Keyword // properties start with a capital letter by convention
{
get; // The get accessor is public, same as the overall property
protected set; // the set accessor is protected
}
The protected set accessor means that this is still accessible to be set by the child classes, but not by anyone else. This is probably what you want. So now, in your child constructor, you can set base.Keyword = "whatever"; and your foreach code can reference, but not overwrite, that value. You can declare GlobalCooldown in a similar way.
I'm a little bit confused with nameof() operator. So for example I can't use class's private fields in nameof() in another class, but I can use public non static fields using non static property, so I don't need instantiated object.
Is it consistently? Why member access modifier does matter for nameof()?
class A
{
private int X;
public int Y;
public A()
{
var x = nameof(A.X);//OK
var y = nameof(A.Y);//OK
}
}
class B
{
public B()
{
var x = nameof(A.X);//Compilation error
var y = nameof(A.Y);//OK
}
}
The purpose of access modifiers like private is to hide the implementation details. They are saying "Nope, you don't need to know this. This is implementation detail". That's why nameof is not allowed to access private properties. Whatever class you are in, that class should not know about the implementation details of some other class.
Static vs non-static is different. Its purpose is not to hide something that you don't need to know about. Its purpose is just to distinguish between members that belongs to instances of the class and members that belongs to the class itself. All you want here is just the name of that member, which requires no instances to be created, so why disallow you? Note that the member is accessible i.e. it's not something you shouldn't know about.
Field X in class A is private. door is locked, you cant access it no matter what you do.
This is not a nameof problem, its Access Modifier problem
Access Modifiers (C# Programming Guide)
All types and type members have an accessibility level, which controls
whether they can be used from other code in your assembly or other
assemblies. You can use the following access modifiers to specify the
accessibility of a type or member when you declare it:
and
public The type or member can be accessed by any other code in the same assembly or another assembly that references it.
private
The type or member can be accessed only by code in the same class or struct.
protected The type or member can be accessed only by code in the same class, or in a class that is derived from that class. internal
The type or member can be accessed by any code in the same assembly,
but not from another assembly.
protected internal The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class
in another assembly.
private protected The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is
derived from that class.
Not a direct answer to your question, but I usually get around this but using a static helper class:
class A
{
public static class Properties
{
public const string X = nameof(A.X);
}
private string X { get; }
}
Then using
A.Properties.X
It's a little bit more verbose, but still enables refactoring tools to work effectively.
I have a generic class definition similar to this:
public sealed class MyClass<TProperty,TOwner>
{
...
}
Now I'd like any instances of MyClass<TProperty,TOwner> regardless of the types of TProperty or TOwner to share a Hashtable. I thought of creating an internal MyClassBase with a protected internal static field of type Hashtable and inherit from that. I really only want the definition of MyClass to have access to this hashtable.
Is this a sound approach? I can't seal MyClassBase, so this probably could lead to opening a can of worms later on...
Are there other approaches for this?
The protected static Hashtable is a fine approach (make sure you synchronize it). You can't have an internal base class whose derived classes are public - but you can prevent it from being derived outside your assembly by making its default constructor internal:
public abstract class MyBaseClass
{
internal MyBaseClass() { }
private static Hashtable _hashtable;
protected static Hashtable Hashtable
{
get
{
if(_hashtable == null)
{
_hashtable = Hashtable.Synchronized(new Hashtable());
}
return _hashtable;
}
}
}
Another option is to make an internal static class with an exposed member, and only access it from MyClass<T,U>. Sure, it'd be visible within your assembly, but that's easily controlled compared to a protected member. Just make sure to only use it in your MyClass<T,U> and it'll be fine.
As far as I know, in C#, there is no support for the "friend" key word as in C++. Is there an alternative way to design a class that could achieve this same end result without resorting to the un-available "friend" key-word?
For those who don't already know, the Friend key word allows the programmer to specify that a member of class "X" can be accessed and used only by class "Y". But to any other class the member appears private so they cannot be accessed. Class "Y" does not have to inherit from class "X".
No, there is no way to do that in C#.
One common workaround is to based the object for which you want to hide the constructor on an interface. You can then use the other object to construct a private, nested class implementing that interface, and return it via a Factory. This prevents the outside world from constructing your object directly, since they only ever see and interact with the interface.
public interface IMyObject
{
void DoSomething();
}
public class MyFriendClass
{
IMyObject GetObject() { return new MyObject(); }
class MyObject : IMyObject
{
public void DoSomething() { // ... Do something here
}
}
}
This is how I solved it. I'm not sure if it's the "right" way to do it, but it required minimal effort:
public abstract class X
{
// "friend" member
protected X()
{
}
// a bunch of stuff that I didn't feel like shadowing in an interface
}
public class Y
{
private X _x;
public Y()
{
_x = new ConstructibleX();
}
public X GetX()
{
return _x;
}
private class ConstructibleX : X
{
public ConstructibleX()
: base()
{}
}
}
No. The closest you have is an internal constructor, or a private constructor and a separate factory method (probably internal, so you haven't saved much).
What about just having it explicity implement an interface that is only visible to a certain class?
Something like:
public void IFreindOfX.Foo() //This is a method in the class that's a 'friend' to class X.
{
/* Do Stuff */
}
and then make sure IFriendOfX is visible to class X. In your X class you'd call the method by first casting X to IFriendOfX then calling Foo(). Another advantage is that is is fairly self documenting... that is, it's pretty close to having the friend keyword itself.
What about creating a private class? This does exactly what you seem to be describing. A member of class X can be accessed and used only by class Y, and to any other class it appears private, since, well, it is private:
public class Y
{
private class X { }
private X Friend;
public Y()
{
Friend = new X();
}
}
As far as I know, the Internal keyword is the closest thing in .NET. This question will shed more light on Internal: Internal in C#
The only thing I can think of that would even come close would be protected internal but that does not restrict it to a specific class. The only friending I'm aware of in c# is to make a friend assembly. Still does not restrict to a specific class.
The only thing I could think of to try and do it would be to do something like the following:
public class A
{
public A() {}
protected internal A(B b) {}
}
public class B
{
A myVersion;
public B()
{
myVersion = A(this);
}
}
The only other way I could think of would be to do some sort of Constructor Injection using reflection that is done inside of your friend class. The injection mechanism would allow you to limit it to what you want but could be very cumbersome. Take a look at something like Spring.Net for some injection capabilities.
As a workaround, I suppose you could create a conditional in your constructor that uses reflection.
For example, if Class1's constructor must be called by Class2:
public Class1()
{
string callingClass = new StackFrame(1).GetMethod().DeclaringType.Name;
if (callingClass != "Class2")
{
throw new ApplicationException(
string.Concat("Class1 constructor can not be called by ",
callingClass, "."));
}
}
EDIT:
Please note that I would never actually do this in "real" code. Technically it works, but it's pretty nasty. I just thought it was creative. :)
You can access private members/methods using Reflection.
Since it's got the design tag, I never particularly liked the friend keyword. It pierces encapsulation and that always felt dirty to me.
This has a bit of a smell. There are other plenty of other ways to achieve implementation hiding in C#. Limiting construction to only specific classes does not achieve all that much.
Could you please provide more information as to the purpose of this requirement? As already answered, internal is the closest match for limiting accessibility to the class. There are ways to build on top of that depending on the purpose.