Passed to class variable not being updated - c#

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();
...

Related

Accessing a singleton class in c# with this;

While searching for ways to get an instance of a singleton class i found many different approaches (some simple, some convoluted) but when messing around i found a way to do it which i didn't find anywhere else.
So what i basically do is:
public class Foo
{
public static Foo Invoker;
public Foo()
{
Invoker = this;
}
public void Method1()
{
//.....
}
}
And then from another class
public class Foo2
{
public Foo2()
{
//.....
}
public void Main()
{
var foo = Foo.Invoker;
//or
Foo.Invoker.Method1();
}
}
My app is single threaded so i don't care about thread safety (should i?) , so are there any other problems that this approach could cause that i am missing?
First of all, your 'singleton' pattern is quite easy to break. Let's say I'd create two instances of Foo in your application (changing the name of the class Foo1 to Bar for clarity):
var firstFoo = new Foo();
var bar = new Bar();
// Will access firstFoo when it calls Foo.Invoker
bar.Main();
var secondFoo = new Foo();
// Will access secondFoo when it calls Foo.Invoker. Huh?
bar.Main();
Another problem: Let's say I use Bar, without having initialized any Foo instances:
var bar = new Bar();
// Will throw a NullReferenceException, because Foo.Invoker is not yet initialized.
bar.Main();
As a rough rule of thumb, you should not set static fields from instances, because it leads to these kinds of situations.
Secondly, Bar probably does not need to know that Foo is a singleton in the first place. You could simply inject Foo in Bar's constructor.
public class Bar
{
private Foo foo;
public Bar(Foo foo) => this.foo = foo ?? throw new ArgumentNullException(nameof(foo));
public void Main()
{
// Now we know it is not null and, for Bar, it does not matter whether it's a singleton or not.
foo.Method1();
}
}
This way you could manage Foo instances easier in your application:
var firstFoo = new Foo();
var bar = new Bar(firstFoo);
// Does not make a difference now.
var secondFoo = new Foo();
This way, you could also leverage dependency injection containers like NInject or Microsoft.Extensions.DependencyInjection to manage your singletons for you.
If you really do want to create a single threaded singleton pattern, I would read Jon Skeet's blog post about singletons (good read!).
The simplest way of creating a singleton would be this approach. This way you create a single instance of Foo on the static property, that can never be changed. But read the blog post for more advanced patterns:
public class Foo
{
public static Foo Invoker { get; } = new Foo();
// Private constructor makes sure the only instance of Foo is created here.
private Foo()
{
}
}
Edit
If you'd want to make sure that all references to Foo in your application point to the last created instance of Foo, you could try something like this:
interface IFoo
{
void Method1();
}
class Foo : IFoo
{
private static int index = 1;
private int id;
private static NestedFoo invoker = new NestedFoo();
public static IFoo Invoker
{
get
{
if (invoker.Instance == null)
{
Create();
}
return invoker;
}
}
private Foo(int id) => this.id = id;
public static IFoo Create()
{
var foo = new Foo(index++);
invoker.Instance = foo;
return invoker;
}
public void Method1()
{
Console.WriteLine(this.id);
}
private class NestedFoo : IFoo
{
public Foo Instance { get; set; }
public void Method1() => Instance.Method1();
}
}
Now you'll always have a reference to the same instance of foo:
var foo = Foo.Create();
foo.Method1(); // 1
var foo2 = Foo.Create();
foo.Method1(); // 2
foo2.Method1(); // 2

Design Pattern for List of Immutable Objects usage

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.

How do I assign a readonly member variable in an object initializer?

class foo {
public readonly int bar;
};
foo a = new foo() { bar = 123 };
error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
How can I assign bar in the object initializer above?
Can I initialize readonly members without having to write a custom constructor for every class/struct ?
To summarize the sentiment of the other answers: The error message isn't helpful— object initializers can't be used with readonly fields.
However, constructors with named arguments can, and the syntax to do so is quite similar.  So similar you might even be thinking that you've seen C# object initializers for readonly fields (like I have been) when what you actually saw was this:
class Foo {
public Foo(int bar) {
this.bar = bar;
}
public readonly int bar;
};
Foo a = new Foo(bar: 123);
// instead of `new Foo() { bar = 123 };`
foo a = new foo() { bar = 123 };
is transformed by the compiler to
foo temp = new foo();
temp.bar = 123;
foo a = temp;
As you can see, the assignment to bar is neither in the foo constructor nor a variable initializer.
So the answer is: you can't.
You pass the value in on the constructor:
public class foo
{
public readonly int _bar;
public foo(int bar)
{
_bar = bar;
}
};
var x = new foo(12345);
What the compiler is telling you is that the only place you can set your readonly field is in the constructor of the class that holds it, this means:
if you need it to change during the lifetime of the object then readonly is not the correct option to use
if each instance of the class needs to hold a custom value in the readonly member variable then you need to inject it as part of the constructor
I would suggest that it isn't a good practice to make your readonly field public like this, instead just expose it as a public property that only has a getter.
class Foo {
private int bar;
public Foo( int bar ){
this.bar = bar;
}
public int Bar {
get { return this.bar; }
}
}
Foo foo = new Foo( 123 );
You can't. You should use the constructor for it.
MSDN
You can't. What the error wants to tell you that you could use
class foo {
public readonly int bar = blabla;
};
The object initializer syntax you're using is just syntax sugar for calling the constructor and the assigning to members. And that' not allowed for readonly members.
You will need to introduce a constructor parameter, and then assign in the constructor. C# is pretty lacking concerning syntax sugar for immutable types.

Change value to a global variable and take it value in other class

I have a global variable in class "X", public int fileCounter = 0;
in a method of this clas I increase the value to n... "fileCounter ++;"
I need to take this value in other class, the problem is at this moment returns the value in 0
how can I do this?
It sounds like you have a public field (or perhaps property) in a class and wish to use that value in another class.
public class Foo
{
public int FileCounter;
public void SomeMethod()
{
FileCounter++;
}
}
public class Bar
{
public void SomeMethod()
{
var foo = new Foo();
foo.SomeMethod();
Debug.WriteLine( string.Format("FileCounter: {0}", foo.FileCounter ) );
}
}
Remember that fields are instance-based unless you declare them as static.

Passing static parameters to a class

As far as I know you can can't pass parameters to a static constructor in C#.
However I do have 2 parameters I need to pass and assign them to static fields before I create an instance of a class. How do I go about it?
This may be a call for ... a Factory Method!
class Foo
{
private int bar;
private static Foo _foo;
private Foo() {}
static Foo Create(int initialBar)
{
_foo = new Foo();
_foo.bar = initialBar;
return _foo;
}
private int quux;
public void Fn1() {}
}
You may want to put a check that 'bar' is already initialized (or not) as appropriate.
You can't pass parameters to a static constructor, but you can pass parameters to the class itself - via generic type parameters.
Slightly crazy this idea, however, I'll just throw it out there anyway.
Make the class generic (with a TypeParam that will provide a parameter type) and place generic constraints on it (details in code example), then derive a new parameter type, which contains virtuals that you can use to read what they want the parameter values to be.
//base parameter type - provides the 'anchor' for our generic constraint later,
//as well as a nice, strong-typed access to our param values.
public class StaticParameterBase
{
public abstract string ParameterString{ get; }
public abstract MyComplexType ParameterComplex { get; }
}
//note the use of the new() generic constraint so we know we can confidently create
//an instance of the type.
public class MyType<TParameter> where TParameter:StaticParameterBase, new()
{
//local copies of parameter values. Could also simply cache an instance of
//TParameter and wrap around that.
private static string ParameterString { get; set; }
private static MyComplexType ParameterComplex { get; set; }
static MyType()
{
var myParams = new TParameter();
ParameterString = myParams.ParameterString;
ParameterComplex = myParams.ParameterComplex;
}
}
//e.g, a parameter type could be like this:
public class MyCustomParameterType : StaticParameterBase
{
public override string ParameterString { get { return "Hello crazy world!"; } }
public override MyComplexType { get {
//or wherever this object would actually be obtained from.
return new MyComplexType() { /*initializers etc */ };
}
}
}
//you can also now derive from MyType<>, specialising for your desired parameter type
//so you can hide the generic bit in the future (there will be limits to this one's
//usefulness - especially if new constructors are added to MyType<>, as they will
//have to be mirrored on this type as well).
public class MyType2 : MyType<MyCustomParameterType> { }
//then you'd use the type like this:
public static void main()
{
var instance = new MyType<MyCustomParameterType>();
//or this:
var instance2 = new MyType2();
}
I did consider a solution that employs custom type attributes applies to a type parameter, however this is easily a better way. However, you'll now be using your class always with a generic parameter type (unless you can use the deriving+specialisation trick) - possibly too clumsy for your liking.
I'd also prefer this over the other solutions presented here as it doesn't require creating any workarounds for the static initialisation - you can still use .Net's guarantee of single-time initialisation.
A word of warning - should you be reviewing your structure?
All that said - remember, though, since you can only parameterise the static once (or in this case, each uniquely parameterised static generic) - I would be asking myself why not just pull the code that is getting the parameters to give to the static, and place it in the static constructor in the first place? That way you don't actually have to resort to strange patterns like this!
I assume you mean static members of a class? In that case, you can do this:
public class MyClass
{
public static int MyInt = 12;
public static MyOtherClass MyOther = new MyOtherClass();
}
Those static members are guaranteed to be instantiated before any class is instantiated.
If you need complex logic, do it in a static constructor:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
static MyClass()
{
MyInt = 12;
MyOther = new MyOtherClass();
}
}
Edit
Based on your edit, I'd say just assign the values to what they need to be before you instantiate the class, like so:
public class MyClass
{
public static int MyInt;
public static MyOtherClass MyOther;
}
// elsewhere in code, before you instantiate MyClass:
MyClass.MyInt = 12;
MyClass.MyOther = new MyOtherClass();
MyClass myClass = new MyClass();
That said, this method gives you no guarantee that MyInt and MyOther are set before MyClass is instantiated. It will work, but requires discipline before instantiating MyClass.
One alternative pattern you might follow looks like this:
public class MyClass
{
private static int MyInt;
private static MyOtherClass MyOther;
private static bool IsStaticInitialized = false;
public static InitializeStatic(int myInt, MyOtherClass other)
{
MyInt = myInt;
MyOther = other;
IsStaticInitialized = true;
}
public MyClass()
{
if(!IsStaticInitialized)
{
throw new InvalidOperationException("Static Not Initialized");
}
// other constructor logic here.
}
}
// elsewhere in your code:
MyClass.InitializeStatic(12, new MyOtherClass());
MyClass myClass = new MyClass();
// alternatiavely:
MyClass myClass = new MyClass(); // runtime exception.

Categories

Resources