Attributes: Access Designation - c#

While I was refering to a book , I got the following statements:
When a data type or method is defined as public , Other Objects can directly access it. When a data type or method is defined as private , only the specific object can access it.
Now this is really confusing. Public and Private are Access Specifiers which only define the scope of a attribute or method.
Why object is mixed with access specifiers? Does object has to do any thing with public , private or protected apart from the fact that if some thing is defined as public then objects too will be able to access irespective of the scope

This is not a scope question but an access limitation modifier. If you declare a function as private that means only that class can call that function.
Public:
Any one can call these functions
Private:
Only that class and the refection engine
Protected:
Only that class and its derived member
Internal:
Public to all the classes in that assembly
A small ex
public class A
{
public int x;
protected int y;
private int z;
}
public class B : A
{
public int CallPro()
{
return y;
}
public int CallPriv()
{
return z; //error
}
}
static void Main()
{
A oa;
oa.x; //Fine
oa.y; //Error
oa.z; //Error
}

Public and Private are Access Specifiers which only define the scope
of a attribute or method.
And that defines the behaviour of the object. Hence the access specifiers are important for the object. Imagine if you have a facade kind of object, you don't want to expose all the details of the operation, rather you want a simple public interface (eg, Save() method) to be exposed for the consumers. That's why you have to consider the specifiers for objects.
public class CustomerFacade()
{
public bool Save(Customer c)
{
VerifyCustomer(c);
// lots of other steps which the caller does not need to know
SaveorUpdateCustomer(c);
}
private void VerifyCustomer(Customer c)
{
}
private void SaveorUpdateCustomer(Customer c)
{
}
}
public class CustomerController()
{
public bool Save(Customer c)
{
return new CustomerFacade().Save(c);
}
}

Related

Passing child method to base constructor

I have a base class that implements some logic and eventually calls an Action which was passed to the contructor.
public class BaseClass
{
private Action action;
public BaseClass(Action someAction)
{
action += someAction;
}
private void doStuff()
{
action();
}
}
Now I want to derive some child classes that implement some specific logic. In these child classes I have a method for that logic and my attempt was to pass this method to the base constructor. But this result in a compiler error CS0120: An object reference is required for the nonstatic field, method, or property 'member'.
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i)
: base(doSpecificStuff) // <-- compiler error CS0120 here
{
b = i;
}
private void doSpecificStuff()
{
// do something depending on b
}
}
I don't quite get why it fails at that point. Is it because the base constructor gets called first which means when calling it I do not have an instance of the child class (including the child's method)?
But why does the compiler asks for a reference to a nonstatic field? Actually I don't see anything static here. Is there a way to get a reference to doSpecificStuff at that point? this.doSpecificStuff does not work, resulting in CS0027: Keyword 'this' is not available in the current context.
Any suggestions for a better design?
This is exactly where object-oriented-design (OOP) and one of its principles, Polymorphism, comes in place, and what it was designed for.
By making doStuff virtual in the base class, we can override the method in the specific class and customize its behavior.
public class BaseClass
{
private Action? action;
public BaseClass(Action someAction)
{
action += someAction;
}
protected BaseClass()
{
}
protected virtual void doStuff()
{
action?.Invoke();
}
}
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i)
{
b = i;
}
protected override void doStuff()
{
// do something depending on b
}
}
I don't quite get why it fails at that point. Is it because the base constructor gets called first which means when calling it I do not have an instance of the child class (including the child's method)?
Sort of. There is actually an instance of the child class (the object is created immediately of the "right" type) but you can't refer to anything specific to the instance in the constructor initializer.
From section 15.11.2 of the draft C# 6 spec:
An instance constructor initializer cannot access the instance being created.
The best way of handling this really depends on the broader context. For example, you could accept a Func<BaseClass, Action> instead and cast:
public class BaseClass
{
private Action action;
public BaseClass(Func<BaseClass, Action> actionProvider)
{
action += actionProvider(this);
}
private void doStuff()
{
action();
}
}
... then:
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i)
: base(x => ((SpecificClass) x).doSpecificStuff)
{
b = i;
}
private void doSpecificStuff()
{
// do something depending on b
}
}
That's a bit tortuous though. If the action is always expected to be a method in the derived class, an option would be to create an abstract method in the base class and just override it in the derived class instead.
The error message means that the compiler is expecting this:
private static void doSpecificStuff()
{
// do something depending on b
}
Why? because when you call your action in doStuff, C# has no way to now that doSpecificStuff has to be called on the current (this) instance.
To compile, you would have to do something like this :
public class BaseClass
{
private Action action;
public BaseClass(Action<BaseClass> someAction)
{
action += () => someAction(this);
}
private void doStuff()
{
action();
}
}
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i): base(x => ((SpecificClass)x).doSpecificStuff()) // <-- compiler error CS0210 here
{
b = i;
}
private void doSpecificStuff()
{
// do something depending on b
}
}
I do not know exactly why you came up with this approach but why not just us inheritance? (Again, there might be some specific need I'm not aware of here, I'm just mentioning this for the record to post an answer as complete as possible) For instance:
public class BaseClass
{
public BaseClass()
{
}
protected virtual void doStuff()
{
// Doing stuff...
}
}
public class SpecificClass : BaseClass
{
private int b;
public SpecificClass(int i): base()
{
b = i;
}
protected override void doStuff()
{
// do something depending on b
base.doStuff()// if needed...
}
}

C# Give access to specific unrelated class

Is there a way to modify the access of some attribute to a specific class? More specifically, I want to create a property that has a public get, but can only be set by a certain class.
Example:
public Class1
{
Class2.SomeInt = 5;
}
public static Class2
{
private static int someInt;
public static int SomeInt
{
get { return someInt; }
(give access to Class1 only somehow?) set { someInt = value; }
}
}
Update (more info):
I'm doing this in xna, I want the main type (Game1) to be the only thing that can modify a static helper class. It's for a group project in school, we're using SVN (not sure how that'd be relevant), I could just tell everyone in my group to avoid setting the values, but I was wondering if there was a better way.
This sounds like the friend access modifier, which C# doesn't have. The closest I've seen to this in C# is to have the "unrelated" class be an interface and have a private implementation within a class. Something like this:
public interface IWidget
{
void DoSomethingPublic();
}
public class SomeObject
{
private ObjectWidget _myWidget = new ObjectWidget();
public IWidget MyWidget
{
get { return _myWidget; }
}
private class ObjectWidget
{
public void DoSomethingPublic()
{
// implement the interface
}
public void DoSomethingPrivate()
{
// this method can only be called from within SomeObject
}
}
}
Code external to SomeObject can interact with MyWidget and sees anything that's on the IWidget interface, but code internal to SomeObject can also non-interface public members on MyWidget.
It seems to be impossible in C#. You can only use public, protected, protected internal, internal and private access modifiers.
But you can, for instance, make an assembly that contains only these two classes and set the internal modifier for the SomeInt setter or nest one class into another.
If you want to just hide a setter from the IntelliSense, you can define this setter in some interface and implement it explicitly:
public interface IHidden<T>
{
T HiddenPropery { set; }
}
public class SomeClass : IHidden<int>
{
private int someInt;
public int HiddenPropery
{
get { return someInt; }
}
int IHidden<int>.HiddenPropery
{
set { someInt = value; }
}
}
Usage:
// This works:
((IHidden<int>)new SomeClass()).HiddenPropery = 1;
// This doesn't:
new SomeClass().HiddenPropery = 1;

Does accessing a static member invoke the base class constructor?

Even though all common sense says no, I still am asking this question just to get a second opinion and become sure.
If I have a class hierarchy like so:
public class IntermediateObjectContext : System.Data.Objects.ObjectContext
{
public static Action<string> PrintHello { get; set; }
}
public class MyDatabaseContext : IntermediateObjectContext
{
public ObjectSet<Foo> Foos
{
get { // ... }
}
}
Then from a third, unrelated to Entity Framework object, if I access the static member of the IntermediateObjectContext class, in this case, if I subscribe to the delegate of the class, will that somehow instantiate a new ObjectContext?
class SomeClass
{
public void SomeMethod()
{
IntermediateObjectContext.PrintHello += SayHello;
}
public void SayHello(string s)
{
Debug.Print(s);
}
}
All reason says no, common sense says it won't, but I just want to make sure. I am trying to track down a memory hogger object.
What happens if
What happens to the memory situation if I have a static collection for SomeClass types like so:
public class SomeClassCollection
{
private static Collection<SomeClass> _col =
new Collection<SomeClass>();
public void Add(SomeClass c) { _col.Add(c); }
public void Remove(SomeClass c) { _col.Remove(c); }
}
And then some code adds SomeClass instances to SomeClassCollection like so:
public SomeClassCollectionConfig
{
public static RegisterSomeClasses()
{
SomeClassCollection.Add(new SomeClass());
SomeClassCollection.Add(new DerivesClassOfSomeClass());
}
}
(1) No, it won't instantiate an object.
(2) What happens if:
There it will allocate the empty collection col the first time any member of SomeClassCollection is accessed.
From the code, that's all it will do. You aren't using _col anywhere in the code presented.

c#: Inherited/interface static member?

Is there a way to require that a class have a particular abstract member? Something like this:
public interface IMaxLength
{
public static uint MaxLength { get; }
}
Or perhaps this:
public abstract class ComplexString
{
public abstract static uint MaxLength { get; }
}
I'd like a way enforce that a type (either through inheritance or an interface?) have a static member. Can this be done?
You could create a custom attribute that allows enforcing the requirement as a runtime guarantee. This is not a fully complete code sample (you need to call VerifyStaticInterfaces in your application startup, and you need to fill in the marked TODO) but it does show the essentials.
I'm assuming you're asking this so you can guarantee successful reflection-based calls to named methods.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)]
internal sealed class StaticInterfaceAttribute : Attribute
{
private readonly Type interfaceType;
// This is a positional argument
public StaticInterfaceAttribute(Type interfaceType)
{
this.interfaceType = interfaceType;
}
public Type InterfaceType
{
get
{
return this.interfaceType;
}
}
public static void VerifyStaticInterfaces()
{
Assembly assembly = typeof(StaticInterfaceAttribute).Assembly;
Type[] types = assembly.GetTypes();
foreach (Type t in types)
{
foreach (StaticInterfaceAttribute staticInterface in t.GetCustomAttributes(typeof(StaticInterfaceAttribute), false))
{
VerifyImplementation(t, staticInterface);
}
}
}
private static void VerifyInterface(Type type, Type interfaceType)
{
// TODO: throw TypeLoadException? if `type` does not implement the members of `interfaceType` as public static members.
}
}
internal interface IMaxLength
{
uint MaxLength
{
get;
}
}
[StaticInterface(typeof(IMaxLength))]
internal class ComplexString
{
public static uint MaxLength
{
get
{
return 0;
}
}
}
This is impossible. Because abstract and virtual method calls are stored in an object though its virtual function pointer table, there is no way that you can enforce any interface requirement on its non-instance members. Calling a static member has no object bound to it, therefore there is no virtual pointer table available.
This isn't a limitation, its just how it is. There is no reason why this would ever be necessary or useful. If you want to enforce an interface, you must do it though instance members.
Not possible. May be you can try something like this:
public class Base
{
public struct MyStruct
{
public static int x = 100;
public static int XX()
{
return 200;
}
}
}
public class Derived : Base
{
public void test()
{
int x = Derived.MyStruct.x;
int XX = Derived.MyStruct.XX();
}
}
References:
Static C#
Suppose class Base includes a static method StaticMethod and an instance method InstanceMethod, both of which return Int32. Class Derived shadows both of those methods with similarly-named methods which return String.
If one casts an instance of derived to a Base and calls InstanceMethod, the call will use Base.InstanceMethod, whose return type is Int32. If one accepts an instance of generic type T, where T inherits Base, and calls InstanceMethod on that, it will likewise call Base.InstanceMethod--again Int32. But what should be the meaning and return type of T.StaticMethod? If one wants Base.StaticMethod, one should specify that. What else could T.StaticMethod usefully mean?

How to restrict access to nested class member to enclosing class?

Is it possible to specify that members of a nested class can be accessed by the enclosing class, but not other classes ?
Here's an illustration of the problem (of course my actual code is a bit more complex...) :
public class Journal
{
public class JournalEntry
{
public JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
// ...
}
I would like to prevent client code from creating instances of JournalEntry, but Journal must be able to create them. If I make the constructor public, anyone can create instances... but if I make it private, Journal won't be able to !
Note that the JournalEntry class must be public, because I want to be able to expose existing entries to client code.
Any suggestion would be appreciated !
UPDATE: Thanks everyone for your input, I eventually went for the public IJournalEntry interface, implemented by a private JournalEntry class (despite the last requirement in my question...)
Actually there is a complete and simple solution to this problem that doesn't involve modifying the client code or creating an interface.
This solution is actually faster than the interface-based solution for most cases, and easier to code.
public class Journal
{
private static Func<object, JournalEntry> _newJournalEntry;
public class JournalEntry
{
static JournalEntry()
{
_newJournalEntry = value => new JournalEntry(value);
}
private JournalEntry(object value)
{
...
If your class is not too complex, you could either use an interface which is publicly visible and make the actual implementing class private, or you could make a protected constructor for the JornalEntry class and have a private class JornalEntryInstance derived from JornalEntry with a public constructor which is actually instantiated by your Journal.
public class Journal
{
public class JournalEntry
{
protected JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
private class JournalEntryInstance: JournalEntry
{
public JournalEntryInstance(object value): base(value)
{ }
}
JournalEntry CreateEntry(object value)
{
return new JournalEntryInstance(value);
}
}
If your actual class is too complex to do either of that and you can get away with the constructor being not completely invisible, you can make the constructor internal so it is only visible in the assembly.
If that too is infeasible, you can always make the constructor private and use reflection to call it from your journal class:
typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });
Now that I think about it, another possibility would use a private delegate in the containing class which is set from the inner class
public class Journal
{
private static Func<object, JournalEntry> EntryFactory;
public class JournalEntry
{
internal static void Initialize()
{
Journal.EntryFactory = CreateEntry;
}
private static JournalEntry CreateEntry(object value)
{
return new JournalEntry(value);
}
private JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
static Journal()
{
JournalEntry.Initialize();
}
static JournalEntry CreateEntry(object value)
{
return EntryFactory(value);
}
}
This should give you your desired visibility levels without needing to resort on slow reflection or introducing additional classes / interfaces
Make JournalEntry a private nested type. Any public members will be visible only to the enclosing type.
public class Journal
{
private class JournalEntry
{
}
}
If you need to make JournalEntry objects available to other classes, expose them via a public interface:
public interface IJournalEntry
{
}
public class Journal
{
public IEnumerable<IJournalEntry> Entries
{
get { ... }
}
private class JournalEntry : IJournalEntry
{
}
}
A simpler approach is to just use an internal constructor, but make the caller prove who they are by supplying a reference that only the legitimate caller could know (we don't need to be concerned about non-public reflection, because if the caller has access to non-public reflection then we've already lost the fight - they can access a private constructor directly); for example:
class Outer {
// don't pass this reference outside of Outer
private static readonly object token = new object();
public sealed class Inner {
// .ctor demands proof of who the caller is
internal Inner(object token) {
if (token != Outer.token) {
throw new InvalidOperationException(
"Seriously, don't do that! Or I'll tell!");
}
// ...
}
}
// the outer-class is allowed to create instances...
private static Inner Create() {
return new Inner(token);
}
}
In this case you could either:
Make the constructor internal - this stops those outside this assembly creating new instances or...
Refactor the JournalEntry class to use a public interface and make the actual JournalEntry class private or internal. The interface can then be exposed for collections while the actual implementation is hidden.
I mentioned internal as a valid modifier above however depending on your requirements, private may be the better suited alternative.
Edit: Sorry I mentioned private constructor but you've already dealt with this point in your question. My apologies for not reading it correctly!
For generic nested class =)
I know this is an old question and it has already an accepted answer, nevertheless for those google swimmers who may have a similar scenario to mine this answer may provide some help.
I came across this question for I needed to implement the same feature as the OP. For my first scenario this and this answers worked just fine. Nevertheless I needed also to expose a nested generic class. The problem is that you can not expose a delegate type field (the factory field) with opened generic parameters without making your own class generic, but obviously this is not what we want, so, here is my solution for such scenario:
public class Foo
{
private static readonly Dictionary<Type, dynamic> _factories = new Dictionary<Type, dynamic>();
private static void AddFactory<T>(Func<Boo<T>> factory)
=> _factories[typeof(T)] = factory;
public void TestMeDude<T>()
{
if (!_factories.TryGetValue(typeof(T), out var factory))
{
Console.WriteLine("Creating factory");
RuntimeHelpers.RunClassConstructor(typeof(Boo<T>).TypeHandle);
factory = _factories[typeof(T)];
}
else
{
Console.WriteLine("Factory previously created");
}
var boo = (Boo<T>)factory();
boo.ToBeSure();
}
public class Boo<T>
{
static Boo() => AddFactory(() => new Boo<T>());
private Boo() { }
public void ToBeSure() => Console.WriteLine(typeof(T).Name);
}
}
We have Boo as our internal nested class with a private constructor and we mantain on our parent class a dictionary with these generic factories taking advantage of dynamic. So, each time TestMeDude is called, Foo searches for whether the factory for T has already been created, if not it creates it calling nested class' static constructor.
Testing:
private static void Main()
{
var foo = new Foo();
foo.TestMeDude<string>();
foo.TestMeDude<int>();
foo.TestMeDude<Foo>();
foo.TestMeDude<string>();
Console.ReadLine();
}
The output is:
The solution Grizzly suggested does make it a bit hard to create the nested class somewhere else but not impossible,like Tim Pohlmann wrote someone can still inherit it and use the inheriting class ctor.
I'm taking advantage of the fact that nested class can access the container private properties, so the container asks nicely and the nested class gives access to the ctor.
public class AllowedToEmailFunc
{
private static Func<long, EmailPermit> CreatePermit;
public class EmailPermit
{
public static void AllowIssuingPermits()
{
IssuegPermit = (long userId) =>
{
return new EmailPermit(userId);
};
}
public readonly long UserId;
private EmailPermit(long userId)
{
UserId = userId;
}
}
static AllowedToEmailFunc()
{
EmailPermit.AllowIssuingPermits();
}
public static bool AllowedToEmail(UserAndConf user)
{
var canEmail = true; /// code checking if we can email the user
if (canEmail)
{
return IssuegPermit(user.UserId);
}
else
{
return null
}
}
}
This solution is not something I would do on a regular day on the job, not because it will lead to problems in other places but because it's unconventional (I've never seen it before) so it might cause other developers pain .

Categories

Resources