This question already has answers here:
Is there an easy way to make an immutable version of a class?
(7 answers)
How do I create an immutable Class?
(8 answers)
Closed 5 years ago.
I want to see if I can make an instance of a class immutable even if the class itself isn't. What I have here is a similar situation to IntPtr.Zero and other static fields like that, except it's a mutable class and not a struct.
class TestClass
{
public static readonly TestClass GoldStandard = new TestClass();
public int field = 0;
}
class Program
{
static void Main(string[] args)
{
TestClass test = TestClass.GoldStandard;
test.field = 1; // I want to keep this from happening.
Console.WriteLine(TestClass.GoldStandard.field);
}
}
What can I do to keep GoldStandard from being modified?
EDIT: I regret that my question was so badly misunderstood. This is clearly not a duplicate of Immutable type and property in C# or How do I create an immutable Class?. Those questions are about how to create an immutable class, and not how to create an immutable instance of a mutable class.
As for Is there an easy way to make an immutable version of a class?, it certainly sounds very similar to my question. However, there are some important reasons it shouldn't count.
The question asks how to make an instance immutable at some point during the instance's lifetime, rather than just having one instance of a mutable class be immutable from the start.
The question asks how an immutable second class can be generated to mimic a mutable class, rather than having one mutable class act as immutable in a specific case.
The answer to the question doesn't even address my question at all, and is mostly about how immutable classes work in general.
I understand moderators can't take too much time to understand the questions in depth when they're scanning for duplicates, but I hardly think it's fair for my question to be closed as a duplicate because of such superficial similarities.
Related
This question already has answers here:
Multiple Inheritance in C#
(13 answers)
Closed 4 years ago.
All similar questions I've looked though here, mentions multiple interface inheritance. However, I am not sure how MII could be a workaround to the problem.
Lets say, I have two library class (My_Class_1 and My_Class_2) of different methods. Then I want to create a new class, that can use both of these classes' methods natively, like:
public class My_Application : My_Class_1, My_Class_2 {
public My_Application(){
method_from_Class1();
smth_property_declared_in_My_Class_2 = "hello";
}
}
However, that is not possible with C#. What are flexible workarounds, to extend/enrich class with other classes? In PHP, that is unbelievably simple, just in the top of the class we can:
use example_trait_1;
use example_trait_2;
I would rather not use interfaces; in my view, they have no relation to solving this problem.
p.s. I don't want to create initialize objects for those classes. I want them to be native part of the application class.
As others mentioned, it isn't possible (because that's not what inheritance is), but it seems one workaround would be to have a public property of type Class1, inside a class that inherits Class2.
That also gets around the problem of "which class am I looking at now?" since you'd need to explicitly mention the property when you want something of type Class1.
And if you need to modify Class1 first, then you just create a separate class that inherits Class1 first, then have the public property be of that new type.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
After reading a lot about immutability in C#, and understading it's benefits (no side effects, safe dictionary keys, multithreading...) a question has come to my mind:
Why there is not a keyword in C# for asserting that a class (or struct) is immutable? This keyword should check at compile time that there is no way you can mutate the class (or struct). For example:
public immutable class MyImmutableClass
{
public readonly string field;
public string field2; //This would be a compile time error
public readonly AnyMutableType field3; //This would be a compile time error
public string Prop { get; }
public string Prop2 { get; set; } //This would be a compile time error
public AnyMutableType Prop3 { get; } //This would be a compile time error
}
I think the compiler work would be quite easy, as it would need to check just a few things:
All public fields are readonly.
All public properties only have getters.
All public fields or properties have immutable types as well (simple value types, or immutable classes/structs).
All public functions or public property getters only depend on immutable fields or properties (public fields/props as described before, or private fields/props which comply to the same restrictions). This of course includes Equals(), GetHashCode() and ToString().
Some possible problems come to my mind with this design:
For the compiler to know that a compiled class/struct is immutable, it would probably be necesary to make changes in the intermediate language.
Readonly generic collection (such as IEnumerable<T>) immutability would depend on the immutability of the type <T>. The proposed immutable keyword would not be useful in this context, as you could not declare that IEnumerable<string> is immutable, even though it is.
Are the reasons stated before enough for this keyword to not exist?
Am I missing any other drawbacks?
Is this just not necessary enough for such big changes in the language?
The short version would be: because nobody has proposed, spec'd, designed, implemented, tested, documented, translated and supported that feature.
The longer version would relate to why to do it, given that it can be achieved indirectly with the readonly field - what benefit would it add.
For classes, it turns out to be relatively minor. Note that there is an [ImmutableObject(true)] attribute that can be used, but no features or frameworks really have a use for it, so ... nobody uses it.
There was a proposal to add "readonly structs" in a future version of C# (related to ref locals, Span<T>, etc) - but: it died a death and evaporated. However, the ref readonly stuff lives on, which is intended to prevent reassignment of this in struct instance methods.
This question already has answers here:
Why do members of a static class need to be declared as static? Why isn't it just implicit?
(8 answers)
Closed 7 years ago.
My question is why members are not by default static in static class.
As we see, interface members are by default public and abstract.
Thanks,
Anil
We should ask c# language designer.
But I understand the ratio behind: it forces the programmer to say "this function is static", even if it would be implied by the fact the the class is static.
Maybe It's a matter of readability: when you read a method without body (and no abstract keyword), you know that this method can only be part of an interface.
When you read a method without "static" modifier, you would need to read also class declaration to understand that is part of a static class and therefore static itself
This question already has answers here:
What is the difference between instantiation in constructor or in field definition?
(5 answers)
Initialize class fields in constructor or at declaration?
(16 answers)
Closed 8 years ago.
Is there any practical difference between those two ways of instantiating an object?
public class myClass
{
private myType myObject = new myType();
}
and
public class myClass
{
private myType myObject;
public myClass()
{
myObject = new myType();
}
}
Thanks for helping.
No there isn't any practical difference, between the two ways you provided. They are exaclty the same.
The answer is yes
When you read the code later, you will look in the constructor to see what happens when you create the class. If you put constructor logic outside the constructor another developer may miss what's going on. So put your constructor logic in your constructor. It makes a difference.
As far as the code goes, there isn't much difference. Initialization in the declaration happens in document order, top to bottom, which might or might not have side effects. From a practical perspective, if you do any interactive debugging at all, you'll grow to hate declaration initializations, unless you enjoy stepping through them one at a time.
Keep your code tidy and initialize things in the constructors.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
This question has to do with best practices... please do not confuse it with premature optimization.
I noticed in .Net that deep object referencing takes quite some time to process when compared to flat or shallow objects. For example:
object1.object2.object3.object4.Property
... is not efficient since, I conclude, each object has to be de-referenced along the path. This is in contrast to C, where Property's memory ref would be calculated by the compiler, rather than at run time.
Now, we obviously wouldn't take all the fields of object2+ and flatten them into object1 just for speed. The coding would be unwieldy and hard to manage. But the speed difference could be significant.
So my question is, "What is the best practice in building deep objects vs. flat(ish) objects?" And, further, is there any advantage to using structs where one is simply trying to group a number of fields together, such as:
public struct SizeData
{
public long Written;
public long Read;
public int Size;
}
The two questions relate.
EDIT
To illustrate:
public class Leaf
{
public int Property;
}
public class Depth1
{
public Leaf Leaf;
}
public class Depth2
{
public Depth1 Depth1;
}
public class Depth3
{
public Depth2 Depth2;
}
private void button12_Click(object sender, EventArgs e)
{
Depth3 depth = new Depth3();
depth.Depth2 = new Depth2();
depth.Depth2.Depth1 = new Depth1();
depth.Depth2.Depth1.Leaf = new Leaf();
Leaf leaf = new Leaf();
var T1 = Environment.TickCount;
for (int i = 0; i < 100000000; i++)
{
depth.Depth2.Depth1.Leaf.Property++;
}
var T2 = Environment.TickCount;
for (int i = 0; i < 100000000; i++)
{
leaf.Property++;
}
var T3 = Environment.TickCount;
MessageBox.Show((T2 - T1).ToString() + Environment.NewLine +
((T3 - T2).ToString()));
}
The only concern here IMHO is not speed, but dependency. Have you ever tried to refactor an application that frequently uses deep object nesting like this? It's a pain in the arse. Have a look at the Law of Demeter (or as I say, the Guideline of Demeter). The idea is that instead of using
person.Address.ZipCode
you instead use something like
person.AddressZipCode
to avoid a dependency on the Address object. Is it faster? Maybe, if you implement it right. But I personally don't care because the speedup is really trivial. All I care about here is reducing dependencies.
The term nested class is usually used to mean "nested type".
class Foo
{
private class FoosHelper { .. }
}
The best practice here is to use them sparingly and prefer private.
But your example is not about nested classes but about nested objects instead:
object1.object2.object3.object4.Property
The best practice would be: build a logical and cohesive object-model first and foremost.
Your suggestion of 'flattening' seems to be about sacrificing the core architecture for a tiny optimization. Not such a good idea.
And to the (only slightly) related struct question:
is there any advantage to using structs where one is simply trying to group a number of fields together
No, usually not. There are rare case where you would need very large arrays of small types but in general using a struct brings only disadvantages.
In my opinion, you shouldn't take the speed into consideration until you realize it's a bottleneck.
The classes/structs should be grouped purely logically: if you see that some class is a part of some other class, that it is needed only inside the bigger class and makes sense only inside the bigger class, then you should put it there and thus avoid polluting namespace. If you see that your smaller class is useful outside the bigger class, define it outside. That simple.
Summing it up: put your class/structure to the deepest appropriate level, but not deeper.
Examples:
myCar.RegistrationDate.Year.IsLeap makes perfect sense, and is much better than myCar.IsRegistrationYearLeap
point.Coordinates.Cartesian.X doesn't make much sense, point.X is much better.
Struct field will not have separate memory allocation then the enclosing object, so there is no difference how deep it is, if all of the nested are structs, it's computed by the compiler.
If you nest the reference types, they have to be dereferenced, and this is not any different from C++.