Lets say I have an object of type Foo, which when initialized, will be immutable. Since these objects are immutable, and I want to be able to access any of these Foo objects, I initialize and store these objects in a static class (FooHandler) which contains a list of all the Foo objects.
Currently however, if a class wants to access this object, I give them the index of where the Foo object is located in the list in FooHandler, and have a getter method to return the object itself when needed. The intent of this is to save on memory by not having two of the same objects in circulation (which I consider a waste).
Is there a better approach in C# for referencing these objects (like a pointer or something similar) or a better structure entirely for how to approach this problem, as I feel giving an index to an immutable object is too hackish and error prone?
Example code:
public class Foo {
public int A { get; private set; }
public int B { get; private set; }
public Foo(int a, int b) {
A = a;
B = b;
}
}
public static class FooHandler {
private static List<Foo> fooList;
static FooHandler() {
fooList = new List<Foo>();
fooList.Add(new Foo(1, 2));
fooList.Add(new Foo(3, 4));
}
// Assume there is error checking
public static Foo GetFoo(int index) {
return fooList[index];
}
}
public class Bar {
public int FooID { get; private set; }
public Bar(int fooID) {
FooID = fooID;
}
public void func() {
Console.WriteLine(FooHandler.GetFoo(FooID).A);
}
}
Note: I know this example could be considered mutable, just wanted to type something up quickly without too much testing.
C# already passes around reference types (denoted by class) with a reference (roughly equivalent to a pointer).
You need not do anything special to get this and it happens automatically. There is no waste in just returning the Foo directly.
Related
So I'm aware of several ways to make private fields accessible to other classes, I just I feel like their must be an easier way because I could do it easier in C++ with pointers.
Basically, I have a class with a large number of integers, that then creates a number of classes that use these integers. But each class only uses a few integers each. What I want is to allow each class to access only the variables that they need, but have all the remaining integers be unaccessible.
Basically what I would do in C++ is:
class PrivateClass
{
private:
int a, b, c, d;
public:
void DoStuff();
};
And then
void DoStuff()
{
ClassOne class_one(&a, &b);
ClassTwo class_two(&c, &d);
//stuff
}
So then class_one has access to the values of a and b, while class_two has access to the values of c and d. (Also, if I've made any errors in my code forgive me, it has been a while since I've actually written in C++)
Given how easy it is to do there, it makes me feel (perhaps erroneously) like there must be a similarly easy method in C#. If not, I'll mostly just make an indexer to encapsulate the variables so that they can be accessed that way.
Edit: Basically I'm getting that I should just use properties like I've been weirdly avoiding. I don't mind making properties for a few fields, but for some reason doing it for 30 or so just feels wrong, like there should be a better way.
The idea of sharing private variables with another class doesn't quite make sense. There are various access modifiers, but that doesn't help if you want one class to have access to certain members, another class to have access to different members, and so forth.
So the first question is how to share variables. Typically we do that with properties.
In this example another class can read A but can't change it. Another class can both read and write B. There is no property for changing _c.
If we want to split hairs, nothing outside the class can actually read or change the variables. They can only access the property, and the property reads/writes the variable.
(You can also do this with auto-properties. You don't need a variable and a separate property. But that's irrelevant for now.)
class PrivateClass
{
private int _a;
private int _b;
private int _c;
public int A => _a;
public int B
{
get { return _b; }
set { _b = value; }
}
};
Next you want to be able to control which classes can "see" which variables.
As long as there are properties, you can't absolutely prevent someone from writing code that calls them. But you can control how one class "sees" another class.
Here's a contrived example. These types don't make much sense.
public class PublicTransportVehicle : IPublicTransport, IMotorVehicle
{
public int PassengerCapacity { get; private set; }
public int PassengerCount { get; set; }
public int AxleCount { get; private set; }
}
public interface IPublicTransport
{
int PassengerCapacity { get; }
int PassengerCount { get; set; }
}
public interface IMotorVehicle
{
int AxleCount { get; }
}
The PublicTransportVehicle class has three int properties. Two are read-only. One is read-write. (I used auto-properties instead of variables. This just means that if set is private then only the class itself can set the property.)
Now I can write a class with a method that takes an argument of type IPublicTransport. I can pass an instance of PublicTransportVehicle or any other class that implements the interface. But the method only sees IPublicTransport. The only properties it knows about are the ones exposed by that interface.
I can write another method that takes an argument of type IMotorVehicle and it only interacts with the properties defined in that interface.
I can pass an instance of PublicTransportVehicle to either method because it implements both interfaces, but each one sees it differently.
Can we absolutely prevent the caller from accessing properties we didn't want it to access? That's a lot harder. For example, a class could do this:
public void DoSomethingWithMotorVehicle(IMotorVehicle motorVehicle)
{
var publicTransportVehicle = motorVehicle as PublicTransportVehicle;
if (publicTransportVehicle != null)
{
publicTransportVehicle.PassengerCount = 1000;
}
}
But we usually can't and shouldn't bother trying to exercise complete control over that. It's practically impossible. The idea is to communicate which properties and methods consumers are expected to interact with. We do that by deliberately making them accessible. If someone wants to something weird like casting an object or using reflection there's not a lot we can do. Unless it's a serious security-related matter we don't need to worry about that.
Private fields, methods, properties, constructors, and events are all meant to be used by the class only. If you want to access these fields from other classes, you can make something like this:
using System;
namespace SharePrivateFields
{
class Supervisor
{
void DoStuff()
{
var subject = new Subject();
var first = new First(subject);
var second = new Second(subject);
}
}
class Subject : IFirstSubject, ISecondSubject
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
interface IFirstSubject
{
int A { get; set; }
int B { get; set; }
}
interface ISecondSubject
{
int C { get; set; }
int D { get; set; }
}
class First
{
private IFirstSubject _subject;
public First(IFirstSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // Completely correct
Console.WriteLine(_subject.C); // `IFirstSubject` does not contain definition for `C`
}
}
class Second
{
private ISecondSubject _subject;
public Second(ISecondSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // `ISecondSubject` does not contain definition for `A`
Console.WriteLine(_subject.C); // Completely correct
}
}
}
However, we're now treading waters of Abstract Factory Design Pattern, which is a more desirable approach in this case.
I'm convinced that the C++ implementation you're mentioning is a flawed design, so it's a reason why you can't make it easy in C# (if we're being completely honest - you can, read about Unsafe code, pointer types, and function pointers; but it's 99% of a time taboo for C# code).
So I suggest you learn about Abstract Factory or at least use my solution for your use-case.
Make the method static and send the corresponding instance to it, then you can access the data you want.
Static Void DoStuff(PrivateClass instance)
{
ClassOne class_one(instance.a, instance.b);
ClassTwo class_two(instance.c, instance.d);
//stuff
}
But the reality is that it is wrong, you should either add reading and writing properties to your variables to be able to send them to DoStuff from outside as a parameter.
//in Main
PrivateClass pClass = new PrivateClass(1,30,2,19);
DoStuff(pClass.A, pClass.B, pClass.C, pclass.D);
//in PrivateClass
namespace Test
{
class PrivateClass
{
private int a;
private int b;
private int c;
private int d;
public PrivateClass(int a, int b, int c, int d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
public int A
{
get
{
return this.a;
}
set
{
this.a = value;
}
}//etc
public static void DoStuff(int a, int b, int c, int d)
{
ClassOne class_one(a, b);
ClassTwo class_two(c, d);
//stuff
}
}
}
This should sound like a really basic question, but I haven't been able to find an answer (even tho I know for sure there are plenty), I guess my Googling skills are bad, or maybe I don't know what to search for.
I have this code:
using System;
public class Program
{
public static void Main()
{
var service = new Service();
service.Execute();
}
}
public class Service
{
private int _foo;
public void Execute()
{
_foo = 1;
var bar = new Bar(_foo);
_foo = 2;
bar.WriteLine();
}
}
public class Bar
{
private readonly int _foo;
public Bar(int foo)
{
_foo = foo;
}
public void WriteLine()
{
Console.WriteLine(_foo);
}
}
How can I make it so it prints 2? (basically the new value after Bar has been initialized)
I tried using ref but no luck.
What you are trying to do doesn't make sense for a value type
Value types and reference types are the two main categories of C#
types. A variable of a value type contains an instance of the type.
This differs from a variable of a reference type, which contains a
reference to an instance of the type. By default, on assignment,
passing an argument to a method, or returning a method result,
variable values are copied. In the case of value-type variables, the
corresponding type instances are copied.
Normally you would create this as a property and set it accordingly
Given
public class Bar
{
public Bar(int foo) => Foo = foo;
public int Foo {get;set;}
public void WriteLine() => Console.WriteLine(Foo);
...
Usage
public void Execute()
{
var bar = new Bar(1);
// set the property instead
bar.Foo = 2;
bar.WriteLine();
...
I have a class Foo, which is a base class for a lot other classes such as Bar and Baz, and I want to do some calculation within Foo using the static members in Bar and Baz, as shown below:
public class Foo{
public result1 {
get{
return field1;
}
}
}
public class Bar : Foo{
public const int field1 = 5;
}
public class Baz : Foo{
public const int field1 = 10;
}
The only solution I can think of is wrap all the fields in a container, add an extra identifier for each object, and use a function to return the fields, like so
Bar : Foo{
public readonly int id = 0;
public static Wrapper wrapper;
}
public Wrapper GetWrapper(int id){
switch(id){
case 0:
return Bar.wrapper;
}
}
However, as you can see, I need to maintain one additional class and function, and I'd rather not to fragment my code. Is there any alternative?
Edit
What you are asking for, i.e. accessing a static or const value in a subclass from a base class is technically possible, but doing so will violate the principals of good SOLID OO design. Also, since you will need an instance of a specific subclass in order to be able to 'reason over' the type of the subclass in order to obtain the appropriate field1, there's little point approaching this problem statically.
Instead, the common, cleaner, approach here is to use subtype polymorphicism which will allow a calling method in the base class, or a method in an external class altogether, to access the appropriate value for 'field1' based on the subclass. This allows control over the value returned to remain inside the appropriate subclasses (i.e. as per your words, the code won't become "fragmented").
Alternative solution using subclass polymorphicism (recommended)
A subclass polymorphic approach (i.e. with the virtual/abstract and override keywords) will allow you to encapsulate the retrieval of a value (or object) which is customizable for each subclass. Here, the abstraction remains conceptually at "give me an integer value", and then the sub-class-specific implementations of 'how' to return the value can be abstracted (hidden) from the caller. Also, by marking the base property as abstract, you will force all subclasses to implement the property, so that the requirement to provide a value isn't forgotten about.
i.e. I would recommend a polymorphic approach like this:
public abstract class Foo
{
public abstract int Result { get; }
}
public class Bar : Foo
{
// This is implementation specific. Hide it.
private const int field1 = 5;
public override int Result
{
get { return field1; }
}
}
public class Baz : Foo
{
public override int Result
{
// No need for this implementation to be a constant ...
get { return TheResultOfAReallyComplexCalculationHere(); }
}
}
If there are no other reusable concrete methods on the base class Foo, then you could also model the abstraction as an interface, with the same effect:
public interface IFoo
{
int Result { get; }
}
Approaching this problem without polymorphicism (Not recommended)
Any compile-time attempt to access static fields on subclasses will typically require code somewhere to switch (or map) on the actually type of the subclass instance, e.g.:
public class Foo
{
public int result1
{
get
{
switch(this.GetType().Name)
{
case "Bar":
return Bar.field1;
case "Baz":
return Baz.field1;
default:
return 0;
}
}
}
public void MethodRequiringValueFromSubclass()
{
Console.WriteLine(result1);
}
}
public class Bar : Foo
{
public const int field1 = 5;
}
public class Baz : Foo
{
public const int field1 = 10;
}
The problem here is that the Open and Closed principal is violated, as each time a new sub class is added, the result1 method would need to be changed to accomodate the new class.
I'd suggest to use abstract function rather that using static member.
public abstract class Foo{
public result1 {
get{
return get_field1();
}
}
protected abstract int get_field1();
}
public class Bar : Foo{
public const int field1 = 5;
protected override int get_field1() { return field1;}
}
public class Baz : Foo{
public const int field1 = 10;
protected override int get_field1() { return field1;}
}
You either add constructor parameter to your Foo class which can be passed from inheritors, thus you don't need extra classes also you'll have less coupling
public class Foo
{
private readonly int _field1;
public Foo(int field1)
{
_field1 = field1;
}
}
or you can use it exactly from inheritors type as static/const members are members of class type
public class Foo
{
public result1
{
get
{
return Bar.field1;
}
}
}
but this gives your code less flexibility and more coupling.
Also you have an option by using virtual properties which you can implement in derrived classes and use in base:
public class Foo
{
public virtual int Field { get { return 0; } }
}
Instead of making Foo abstract as other answers suggested you can use virtual and override result1 in each child class
public class Foo
{
public virtual int result1 { get; }
}
public class Bar : Foo
{
public const int field1 = 5;
public override int result1
{
get { return field1; }
}
}
public class Baz : Foo
{
public const int field1 = 10;
public override int result1
{
get { return field1; }
}
}
If you want default result1 to return something else than 0 you can give it another value
public class Foo
{
public virtual int result1 { get; } = -1;
}
I always feel like a jerk when I answer my own question... Yet didn't see what I was expecting so I might as well just share what I've got after a night of mind boggling.
The reason I don't want to make the calculation abstract/virtual is because there are many subclasses and the formula is the same for all of them. I just refuse to type the same code 10-20 times repeatedly.
Couldn't make the static fields non static either, as they should be accessible at a class level plus they can get big, and they are the same for all instances.
The only solution I can come up that minimizes code fragment is something like this
public class Foo {
public class Wrapper {
Fields...
}
public Wrapper wrapper; // reference
public int result1 { get; }
}
public class Bar : Foo {
public static Wrapper subclassWrapper; // put in the implementation
public Bar() : base(){
wrapper = subclassWrapper;
}
}
So each instance now needs to hold an extra reference, however I don't need to keep a function. The wrapper is kept within the base class so it is less fragmented.
Ok, so here's the basic code:
class foo
{
String name;
int property;
}
class bar
{
private List<foo> a;
private List<foo> b;
}
I'd like to make it so that calling code can iterate over either list but I want to keep them protected from editing. I've looked into implementing the IEnumarable interface but the problem is that it expects a single "GetEnumerable" definition, but I want two different enumerators. For instance, i want to be able to say
foreach(foo in bar.getA())
{ //do stuff }
and then
foreach(foo in bar.getB())
{ //do stuff }
Do I have to subclass each element and implement the IEnumerable interface over each, and then include THOSE as properties? Am I misunderstanding the IEnumerable interface? I know that the List class has it's own Enumerator, so I could do something like
class bar
{
private List<foo> a;
private List<foo> b;
public IEnumerator<foo> getAEnumerator()
{ return a.GetEnumerator();
public IEnumerator<foo> getBEnumerator()
{ return b.GetEnumerator();
}
but then my for loops look like this:
bar x = new bar();
IEnumerator<foo> y = x.getAEnumerator();
while (y.moveNext())
{
foo z = y.Current;
}
so I lose the readability of "foreach".
Is there a way to accomplish using "foreach" over these lists without exposing these lists publicly? I'm still trying to get my head around the IENumerable interface, so maybe I'm missing something obvious.
Don't expose a List<T>, expose something else, like an IReadOnlyList<T> instead:
class bar
{
private readonly List<foo> a = new List<foo>();
private readonly List<foo> b = new List<foo>();
public IReadOnlyList<foo> A { get; private set; }
public IReadOnlyList<foo> B { get; private set; }
public bar()
{
A = a.AsReadOnly();
B = b.AsReadOnly();
}
}
Any changes to a and b will reflect in A and B.
Also note that while you can cast a List<T> to an IReadOnlyList<T>, the calling code can cast it back to List<T>. The above method returns a ReadOnlyCollection<T> which provides a safeguard against casting back to a mutable collection type.
The readonly keyword only ensures you don't substitute references to a and b with something else later on.
class bar
{
private readonly List<foo> a = new List<foo>();
private readonly List<foo> b = new List<foo>();
public IReadOnlyList<foo> A { get {return a.AsReadOnly();}}
public IReadOnlyList<foo> B { get {return b.AsReadOnly();}}
}
this way you'll not even have to initialize it, and no need to any kind of set
Considering the following case in C#:
class Foo
{
public Foo() { }
}
class Foo2
{
private List<Foo> m_List = new List<Foo>();
public Foo2() { m_List.Add(new Foo); }
}
Foo2 fooInstance = new Foo2();
Foo2 owns a List that contains a Foo - is there any built-in way for the Foo to figure out which List it's contained in, and which object that list belongs to? In other words, can Foo obtain a reference to Foo2, or do I have to add an explicit backwards reference in Foo - pointing to Foo2 - as I've been doing?
No, there's no built-in way. Instances of Foo only know about themselves, the public interface of their members, and the public/protected interface of their base class, if they have one.
If you give a little more context about what you're trying to do, I may be able to offer you an alternative solution.
Foo will have no knowledge that it is contained within a list unless you specify that somehow. A list after all is just a set of references to a location in memory. There is no relationship from a pointer to what contains the pointer.
class Foo
{
public Foo2 Parent { get; protected set; }
public Foo(Foo2 parent)
{
Parent = parent;
}
}
class Foo2
{
public Foo2()
{
List<Foo> x = new List<Foo>
{
new Foo(this)
};
}
}
No; that's inherently impossible.
What if you put the same object in two lists?