Background: I have enclosed (parent) class E with nested class N with several instances of N in E. In the enclosed (parent) class I am doing some calculations and I am setting the values for each instance of nested class. Something like this:
n1.field1 = ...;
n1.field2 = ...;
n1.field3 = ...;
n2.field1 = ...;
...
It is one big eval method (in parent class). My intention is -- since all calculations are in parent class (they cannot be done per nested instance because it would make code more complicated) -- make the setters only available to parent class and getters public.
And now there is a problem:
when I make the setters private, parent class cannot acces them
when I make them public, everybody can change the values
and C# does not have friend concept
I cannot pass values in constructor because lazy evaluation mechanism is used (so the instances have to be created when referencing them -- I create all objects and the calculation is triggered on demand)
I am stuck -- how to do this (limit access up to parent class, no more, no less)?
I suspect I'll get answer-question first -- "but why you don't split the evaluation per each field" -- so I answer this by example: how do you calculate min and max value of a collection? In a fast way? The answer is -- in one pass. This is why I have one eval function which does calculations and sets all fields at once.
You could declare inside E a private interface IN, explicitly implemented by N. This interface would expose the members of N accessible only by E :
public class E
{
public void Foo()
{
IN n = new N();
n.Field1 = 42;
}
public class N : IN
{
private int _field1;
int IN.Field1
{
get { return _field1; }
set { _field1 = value; }
}
}
private interface IN
{
int Field1 { get; set; }
}
}
If it's possible for you to put the parent and child classes in another assembly, you can make use of internal for the setters. That's generally how this is dealt with in the wild.
EDIT:
Thomas Levesque's answer gave me an idea:
class Program
{
static void Main(string[] args)
{
E myE = new E();
Console.WriteLine("E.N1.Field1 = " + myE.N1.Field1);
Console.WriteLine("E.N2.Field1 = " + myE.N2.Field1);
}
public interface IN
{
int Field1 { get; }
}
public class E
{
private N _n1 = new N();
private N _n2 = new N();
public E()
{
_n1.Field1 = 42;
_n2.Field1 = 23;
}
public IN N1
{
get { return _n1; }
}
public IN N2
{
get { return _n2; }
}
private class N : IN
{
private int _field1;
public int Field1
{
get { return _field1; }
set { _field1 = value; }
}
}
}
}
Depending on how you need to expose the child class N, this could work.
Another alternative is to leave the members you wish to be private public if your (nested) class is private. If fields of private class is public, its only going to be exposed to the enclosing class.
public class E
{
public void Foo()
{
IN n = new N();
n.field1 = 42;
}
class N : IN
{
public int _field1;
}
}
Now N is only visible to E, so n._field1 being public only matters to E, and you're safe..
This is an old question, but here goes a possible solution that doesn't use interfaces.
You can have a static function in the inner class which sets up delegates in the outer class, like so:
public class Outer {
private delegate void _operateDlg(Inner inner, bool value);
private static _operateDlg _validate;
static Outer() {
Inner.Init();
}
public void Set(Inner inner, bool value) {
_validate(inner, value);
}
public class Inner {
public bool IsValid {get; private set; }
public static void Init() {
Outer._validate += delegate(Inner i, bool value) {
i.IsValid = value;
};
}
}
}
You can put all kinds of different delegates in the outer class that you assign with the Inner.Init() method, such as methods which return an instance of the Inner class through a private constructor or getters/setters of a particular field.
If you don't mind having an extra Init() static function in your inner class, then this doesn't have to change. But if you don't want the Init() method to be visible, you can use reflection to call it:
using System.Reflection;
public class Outer {
private delegate void _operateDlg(Inner inner, bool value);
private static _operateDlg _validate;
static Outer() {
typeof(Inner).GetMethod("Init",
BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
}
public void Set(Inner inner, bool value) {
_validate(inner, value);
}
public class Inner {
public bool IsValid {get; private set; }
private static void Init() {
Outer._validate = delegate(Inner i, bool value) {
i.IsValid = value;
};
}
}
}
I know that one could use Reflection to bypass private access restrictions anyway, but using it just to call one single Init() method which then assigns the appropriate delegates is a much cleaner and more versatile solution in my opinion. The alternative would be calling reflection for every single delegate you might want to create, and even then there could be limitations (such as the inability to create delegates to constructors).
The above solution not only supports wrapping constructors, but it will only use Reflection once in the lifetime of a program, so there shouldn't be a noticeable performance penalty other than the fact that you're using delegates to achieve what should have been allowed as direct access in the first place. I don't know why C# doesn't support this, and I can't think of a good reason why it doesn't.
make the fields "protected internal"
if the nested classes are private you could use obly "internal" to those fields.
Related
Base Class
class TestBase
{
protected int a;
protected int b;
public TestBase(int i)
{
a = i;
}
protected TestBase()
{
}
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.Update("Hello World ");
}
Child Class
class TestChild:TestBase
{
private string msg;
public void Update (string s)
{
msg = s+ a.ToString();
Console.WriteLine("msg=" + msg);
}
}
Calling
private void btnTest_Click(object sender, EventArgs e)
{
TestBase t = new TestBase(1);
t.Update(100);
}
Result
Hello World 0
Problem
I was hoping to get Hello World 100. Obviously the child class did not access base class variable int a. how can I do that?
First of all, it's not clear what you're trying to accomplish.
There are many problems with this code. First, you should not be creating an instance of TestChild inside a TestBase class method. If you create an instance of TestBase inside btnTest_Click, then there is no way you'll be able to access any of TestChild's methods or data (except that you are creating an instance of TestChild inside TestBase which is bad practice).
The purpose of inheritance is usually to extend the data/methods for a base class, not to use an inherited class inside a base class. Also, with a set of inherited classes, you can achieve polymorphism which is another core principle of Object Oriented Programming. You should get a better understanding of these principles and then the code will start making more sense.
The object you created in TestBtn_Click has nothing to do with the object you created in TestBase.Update. They are two different objects so each have their own a field with different values.
To produce the output you expect, you need to set child.a to this.a in Update:
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.a = this.a;
child.Update("Hello World ");
}
The important thing to understand here is that inheritance does not affect objects. Inheritance only affects classes. The base class members will also be present in the subclass. That's it. Even though objA's type inherits from objB, they are unrelated unless they are the same object.
public void Update(int i)
{
a = i;
TestChild child = new TestChild();
child.Update("Hello World ");
}
This is where you are assigning value to variable a, and later you instantiated another instance of TestChild class which is different.
After this instantiation you have to assign the value like
TestChild child = new TestChild();
child.a = i;
child.Update("Hello World ");
Then you shall get your desired result
The child object inside your TestBase doesn't know where is he placed. It doesn't know it is inside of a class.
When you create the child you also create a totally different TestBase object which is not the same as what contains the child. When you create that object a will be initialized to a default value which is 0 in this case.
If you would like to carry the value of a to an other object you should give it to it. For example through the constructor.
Call like this:
TestChild child = new TestChild(a);
Make a constructor like this:
public TestChild(int x) : base(x){}
Unfortunately your concept bleeding from everywhere so it will not work in this form. I recommend to study inheritance more.
This is how to use inheritance:
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Dalmata", "Fuffy", 7);
}
}
class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public Animal(string name, int age)
{
Name = name;
Age = age;
}
}
class Dog : Animal
{
public string Race { get; set; }
public Dog(string race, string name, int age) : base(name, age)
{
Race = race;
}
}
This way, you will acess Name and Age too, even if they are declared in Animal.
you should call your base class this way
class BaseClass
{
int a;
int b;
protected BaseClass()
{ }
protected BaseClass(int i)
{
a = i;
}
protected void Update(int i)
{
a = i;
Console.Write("Hello World ");
}
}
class TestChild : BaseClass
{
public TestChild(int i) : base(i) //send your constuctor to your base class
{ }
public TestChild()
{ }
public void Update(int i)
{
base.Update(i);
Console.Write(i.ToString());
}
}
private void btnTest_Click(object sender, EventArgs e)
{
TestChild t = new TestChild(); // create instance as your child
t.Update(100);
}
create your object as your child class then call your method and let it call your base class
also if wanna access a or b in base class from your child
public int a;
public it so you can access it from instance you created
protected will allow only inside child class to access to it
If you'd like to get the expected result, put a static modifier front of a and/or b variables, like this:
static protected int a;
static protected int b;
After this, if you push that button it will write out:
msg=Hello World 100
I wrote the following console app to test static properties:
using System;
namespace StaticPropertyTest
{
public abstract class BaseClass
{
public static int MyProperty { get; set; }
}
public class DerivedAlpha : BaseClass
{
}
public class DerivedBeta : BaseClass
{
}
class Program
{
static void Main(string[] args)
{
DerivedBeta.MyProperty = 7;
Console.WriteLine(DerivedAlpha.MyProperty); // outputs 7
}
}
}
As this console app demonstrates, the MyProperty property exists once for all instances of BaseClass. Is there a pattern to use which would allow me to define a static property which will have allocated storage for each sub-class type?
Given the above example, I would like all instances of DerivedAlpha to share the same static property, and all instances of DerivedBeta to share another instance of the static property.
Why am I trying to do this?
I am lazily initializing a collection of class property names with certain attributes (via reflection). The property names will be identical for each derived class instance, so it seems wasteful to store this in each class instance. I can't make it static in the base class, because different sub-classes will have different properties.
I don't want to replicate the code which populates the collection (via reflection) in each derived class. I know that one possible solution is to define the method to populate the collection in the base class, and call it from each derived class, but this is not the most elegant solution.
Update - Example of what I'm doing
At Jon's request, here's an example of what I'm trying to do. Basically, I can optionally decorate properties in my classes with the [SalesRelationship(SalesRelationshipRule.DoNotInclude)] attribute (there are other attributes, this is just a simplified example).
public class BaseEntity
{
// I want this property to be static but exist once per derived class.
public List<string> PropertiesWithDoNotInclude { get; set; }
public BaseEntity()
{
// Code here will populate PropertiesWithDoNotInclude with
// all properties in class marked with
// SalesRelationshipRule.DoNotInclude.
//
// I want this code to populate this property to run once per
// derived class type, and be stored statically but per class type.
}
}
public class FooEntity : BaseEntity
{
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_A { get; set; }
public int? Property_B { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_C { get; set; }
}
public class BarEntity : BaseEntity
{
public int? Property_D { get; set; }
[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
public int? Property_E { get; set; }
public int? Property_F { get; set; }
}
Desired end result
Accessing FooEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_A",
"Property_C"
}
Accessing BarEntity.PropertiesWithDoNotInclude returns a List<string> of:
{
"Property_E"
}
Two possible approaches:
Use attributes; decorate each subclass with an attribute, e.g.
[MyProperty(5)]
public class DerivedAlpha
{
}
[MyProperty(10)]
public class DerivedBeta
{
}
That only works when they're effectively constants, of course.
Use a dictionary:
var properties = new Dictionary<Type, int>
{
{ typeof(DerivedAlpha), 5) },
{ typeof(DerivedBeta), 10) },
};
EDIT: Now that we have more context, Ben's answer is a really good one, using the way that generics work in C#. It's like the dictionary example, but with laziness, thread-safety and simple global access all built in.
Jon has a good solution as usual, although I don't see what good attributes do here, since they have to be explicitly added to every subtype and they don't act like properties.
The Dictionary approach can definitely work. Here's another way to do that, which explicitly declares that there will be one variable per subclass of BaseEntity:
class FilteredProperties<T> where T : BaseEntity
{
static public List<string> Values { get; private set; }
// or static public readonly List<string> Values = new List<string>();
static FilteredProperties()
{
// logic to populate the list goes here
}
}
The drawback of this is that it's rather difficult to pair with a GetType() call such as you might use in methods of BaseEntity. A Dictionary, or wrapper thereto which implements lazy population, is better for that usage.
I just recently needed this same thing and came across this question. I think Jon's and Fried's ideas to use a Dictionary are on the right track but don't quite hit what I was looking for so I thought I'd show my own complete and very easy to extend implementation.
public class TypeStaticProperty<T>
{
T _defaultValue;
Dictionary<Type, T> _values = new Dictionary<Type, T>();
public TypeStaticProperty(T defalutValue = default)
{
_defaultValue = defalutValue;
}
public T Get(object caller)
{
lock (_values)
{
if (_values.TryGetValue(caller?.GetType(), out T val))
return val;
else
return _defaultValue;
}
}
public void Set(object caller, T val)
{
lock (_values)
_values[caller?.GetType()] = val;
}
}
And to demonstrate:
class TestBaseClass
{
static TypeStaticProperty<int> _property = new TypeStaticProperty<int>();
public int Property
{
get => _property.Get(this);
set => _property.Set(this, value);
}
}
class TestClass1 : TestBaseClass
{
}
class TestClass2 : TestBaseClass
{
}
class Program
{
static void Main(string[] args)
{
TestClass1 test1a = new TestClass1();
TestClass1 test1b = new TestClass1();
test1a.Property = 1;
test1b.Property = 2;
TestClass2 test2a = new TestClass2();
TestClass2 test2b = new TestClass2();
test2a.Property = 3;
test2b.Property = 4;
Console.WriteLine($"test1a.Property = {test1a.Property}");
Console.WriteLine($"test1b.Property = {test1b.Property}");
Console.WriteLine($"test2a.Property = {test2a.Property}");
Console.WriteLine($"test2b.Property = {test2b.Property}");
}
}
Output:
test1a.Property = 2
test1b.Property = 2
test2a.Property = 4
test2b.Property = 4
So while you still need a class instance to access and set the property, the value will always be the same across all instances of that precise type. (This includes generics too; Foo<int> will be seen as a different type than Foo<string>). This has the huge advantage over Fried's example in that you don't need to know at compile time the precise type whose "static" value you're looking for when accessing or setting.
PS - For full disclosure, this was heavily inspired by the WPF source code, which uses a very similar pattern for DependencyProperty's and all kinds of other internal bells and whistles designed to improve performance and reduce memory footprint.
I have error
Cannot access a non-static member of outer type 'Project.Neuro' via
nested type 'Project.Neuro.Net'
with code like this (simplified):
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = OtherMethod(); // error is here
}
}
public int OtherMethod() // its outside Neuro.Net class
{
return 123;
}
}
I can move problematic method to Neuro.Net class, but I need this method outside.
Im kind of objective programming newbie.
Thanks in advance.
The problem is that nested classes are not derived classes, so the methods in the outer class are not inherited.
Some options are
Make the method static:
class Neuro
{
public class Net
{
public void SomeMethod()
{
int x = Neuro.OtherMethod();
}
}
public static int OtherMethod()
{
return 123;
}
}
Use inheritance instead of nesting classes:
public class Neuro // Neuro has to be public in order to have a public class inherit from it.
{
public static int OtherMethod()
{
return 123;
}
}
public class Net : Neuro
{
public void SomeMethod()
{
int x = OtherMethod();
}
}
Create an instance of Neuro:
class Neuro
{
public class Net
{
public void SomeMethod()
{
Neuro n = new Neuro();
int x = n.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
you need to instantiate an object of type Neuro somewhere in your code and call OtherMethod on it, since OtherMethod is not a static method. Whether you create this object inside of SomeMethod, or pass it as an argument to it is up to you. Something like:
// somewhere in the code
var neuroObject = new Neuro();
// inside SomeMethod()
int x = neuroObject.OtherMethod();
alternatively, you can make OtherMethod static, which will allow you to call it from SomeMethod as you currently are.
Even though class is nested within another class, it is still not obvious which instance of outer class talks to which instance of inner class. I could create an instance of inner class and pass it to the another instance of outer class.
Therefore, you need specific instance to call this OtherMethod().
You can pass the instance on creation:
class Neuro
{
public class Net
{
private Neuro _parent;
public Net(Neuro parent)
{
_parent = parent;
}
public void SomeMethod()
{
_parent.OtherMethod();
}
}
public int OtherMethod()
{
return 123;
}
}
I think making an instance of outer class in inner class is not a good option because you may executing business logic on outer class constructor. Making static methods or properties is better option. If you insist making an instance of outer class than you should add another parameter to outer class contructor that not to execute business logic.
I need a certain class to contain a static member that keeps track of everytime an instance of that class is instantiated, essentially so that each instance of the class has a unique index. It works with a non-generic class but this generic implementation fails whenever the type T differs between instances:
class A<T>
{
private static int counter;
private static int Counter {
get {
Increment();
return counter;
}
}
private static void Increment() {
counter++;
}
public int Index;
public A()
{
this.Index = Counter; // using A<T>.Counter makes no difference
Console.WriteLine(this.Index);
}
}
class Program
{
static void Main(string[] args)
{
var a = new A<string>();
var b = new A<string>();
var c = new A<string>();
var d = new A<int>();
}
}
The output is:
1
2
3
1
As soon as the type T switches to int instead of string, the counter resets.
Does this fail by design, and if so what is the reason or how can I get around it? Or is it a bug? It makes sense to some degree because the type T, being generic, is in the class declaration, but..
Each different T creates a new class for A<T> and hence distinct static counters.
To get around this you can use inheritance like so:
abstract class A
{
protected static int counter;
}
class A<T> : A
{
private static int Counter {
get {
Increment();
return counter;
}
}
private static void Increment() {
counter++;
}
public int Index;
public A()
{
this.Index = Counter;
Console.WriteLine(this.Index);
}
}
Not a bug - this is by design, and is a consequence of how generics work.
A generic type like your A<T> serves as a template - when you use type parameters, the compiler generates an actual class with that type T, and a different one will be created for each different type T.
This explains the results you see - there is a static field for the A<int> and another one for the A<string>.
This is because different types are generated under the hood for classes with different generic type parameters. This difference is only for the value type parameters as kindly noted by Ben in comment.
Check out these MSDN articles:
Generics in the Run Time
Reflection and Generic types
EDIT:
Consider following code:
public abstract class GenericBase<T>
{
public static int Counter { get; set; }
}
public class GenericInt : GenericBase<int>
{
}
public class GenericLong : GenericBase<long>
{
}
public class GenericDecimal : GenericBase<decimal>
{
}
[TestFixture]
public class GenericsTests
{
[Test]
public void StaticContextValueTypeTest()
{
GenericDecimal.Counter = 10;
GenericInt.Counter = 1;
GenericLong.Counter = 100;
// !! At this point value of the Counter property
// in all three types will be different - so does not shared across
// all types
}
}
A generic class is a template from which other classes are created. A List<String> and a List<int> are two completely different classes, despite them both originating from List<T>.
Have your generic classes reference a non-generic class that holds the counter. Do not put the static class inside the generic class. This will cause the static class to be generated for each value of T.
class A<T>
{
private static int Counter {
get {
ACounter.Increment();
return ACounter.counter;
}
}
public int Index;
public A()
{
this.Index = Counter;
Console.WriteLine(this.Index);
}
}
static class ACounter
{
static ACounter() {
counter = 0;
}
public static int counter {get; private set;};
public static void Increment() {
counter++;
}
}
Generics with different type parameters are different types. So A<int> and A<string> are different classes, and so are allocated different statics.
This is by design. An instance of A<int> is not an instance of A<string> they are different classes so there are 2 static variable one for each class.
A<int> is actually a different class than A<string>, hence they have different static counters
This is why Resharper flags static variables in generics because so few programmers seems to understand statics and especially statics in generics
I'm trying to provide two classes to my users - one that is read-only and one that is writable. The r/o will only have getters, while the writable will inherit from it and add the setters.
I was under the impression that C# should be able to handle it, but the compiler disagreed.
Why doesn't this work? Any workarounds?
class A
{
protected int m_val;
public int Val
{
get { return m_val; }
}
}
class B : A
{
public int Val
{
set { m_val = value; }
}
}
class Test
{
static void Main(string[] args)
{
B b = new B();
b.Val++; // <-- WHY DOESN'T THIS WORK?!
}
}
P.S. the protected variable in the example above is artificial. My class actually wraps some native resources and the getting/setting happens on either const or mutable native pointer.
partial applies to a single type - not 2 types (A and B). You would need something more like below, ideally keeping the field private:
class A
{
private int m_val;
public int Val
{
get { return m_val; }
protected set { m_val = value; }
}
}
class B : A
{
public new int Val
{
get { return base.Val;}
set { base.Val = value; }
}
}
I'm not sure about why you need this, but a possibly better design would be to have two interfaces rather than two classes, and a single class that implements both. Then you could hand your client code whichever interface you'd like them to use, with the added bonus of being able to use the values set on a writable interface and hand it over to someone else as a read-only interface.
Mark the setters as protected in the parent, and expose public setters in the child.