Class Member Instantiation - c#

public class ClassA
{
private SomeOtherClass _someOtherClass = new SomeOtherClass();
}
or
public class ClassB
{
private SomeOtherClass _someOtherClass;
public ClassB()
{
_someOtherClass = new SomeOtherClass();
}
}
or
public ClassC
{
SomeOtherClass _someOtherClass
public SomeOtherClass someOtherClass
{
get{
if(_someOtherClass == null)
{
_someOtherClass = new SomeOtherClass();
}
return _someOtherClass;
}
}
}
All of the above accomplish populating a property with an instance of an object. Is there a benefit to one of them over the other ones? In practice, I only use C when I don't have control over the construction of a class (like in a GUI). A smells a bit to me, but I don't have a concrete reason for that smell.
Note I am omitting the Inversion Of Control (IOC) pattern from the discussion as the benefits of that are well known and I of course use it often. This question is more about the case of a simple class that may not need that pattern.

A and B are almost the same (implementation details on the order, but not important in this case).
I would use C when:
The initialization of the variable can be delayed, or isn't frequently used;
I want to optimize the initialization time and memory of the class.
Another option for C is the use of Lazy<T>, but that is out of scope for the question I think.

A and B are (as said in other answers) basically the same. The property is populated when the class is constructed.
C doesn't populate the property on construction of the class, but only when it's accessed, which can be useful for a number of reasons (for example performance). Furthermore, it also has the side-effect that the property will never be able to be 'null' (whenever it's accessed, which could be an advantage or a disadvantage, depending on what the property is used for.

Well, the first and second example works the same, but I can say that the second one is much cleaner than the first one, because the instantiation is in the constructor, and the purpose of the constructor is usually to initialize the object's members that can be defined at that moment. In this way, you can easily know what has been instantiated just by looking at the constructor, and not searching through all the fields. In any of the first two cases, you could mark the field as readonly if you don't change it's value after that.
I see the third one as a kind of lazy loading, because you will initialize the field when you get the property. I use this when I am not sure if I will use the object within the class, so it is created per request. However, it has the minimal overhead of checking everytime if the field is instantiated, but it's nothing to worry about with current hardware. If you will use the object only within the class, you can mark the property as private, because it has no reason to be seen from the outside.

Related

Readonly field vs abstract getter-only property

What are the advantages and disadvantages of having a readonly field compared to having inheritors implement an abstract getter-only property (using C# as an example here, but I guess that doesn't really matter much).
Here are both ways to do this:
readonly field; inheritors have to inject the value in the constructor
interface IFace {
public int Field { get; }
}
abstract class Base : IFace {
private readonly int field;
protected Base(int field) {
this.field = field;
}
public int Field { get { return this.field; } }
}
class Impl {
public Impl() : base(1) {
}
}
abstract getter-only property; inheriters have to implement the property
interface IFace {
public int Field { get; }
}
abstract class Base : IFace {
// default constructor can be used
public abstract int Field { get; }
}
class Impl {
public override int Field { get { return 1; } }
}
Both implementations expose a public int Field getter-only property which does not change.
However, I can see the following differences:
The value of field is bound to each instance and there's nothing preventing inheritors from allowing to receive the value in their constructors themselves (public Impl(int field) : base(field)).
Being bound to an instance, memory for the field is required for each single instance. Which might not be a big deal, but it's definitely something to keep in mind.
The conveyed intent is: the value can only be set in the constructor and cannot change later on (leaving aside reflection).
The (returned) value of Field is bound to each type, but there's nothing preventing inheritors from generating/calculating the value each time the getter is called, potentially returning a different value each time. public overried int Field { get { return DateTime.UtcNow.Second; } }
Memory is only required "in IL", since the value is (usually) not stored anywhere, but always computed before being returned (resulting in a load instruction and nothing more).
The conveyed intent should be: the value is bound to the type (and shouldn't change between calls, but there's no way to force that, right?). But rather the intent comes across as: you need to provide this property, I don't care how you implement it and which value it returns.
Are there any crucial differences I'm missing? Is one preferred over the other, or is it required to decide on a case-by-case basis?
I guess I'm looking for a construct/pattern/language feature which binds readonly (constant) values to a type, but expose the value at the instance level. I know that I can use static fields in each inheriting type, but there's no way to enforce this from a common base (or interface). Furthermore, static fields cannot be called when having only a reference to an instance of this type. Thoughts? I'm happy to receive answers in different programming languages
There is one crucial difference between pattern 1 and pattern 2 you have given.
Pattern 1 does not allow to return a different value once class is constructed because base class takes field only in constructor.
Pattern 2 allows child classes to return different values at different times. Basically - there is nothing enforced from base class if child class decides to override.
Thus - it really depends what you want to achieve and your domain logic.
Regarding the intent you are trying to achieve - in my opinion - one of the ways to tackle the implement the intention is declare a virtual method (something like getReadOnlyField() in base) rather than a read-only property. Then - child classes are free to override the virtual method - if they do not override - base implementation will still be enforced.
There cannot be any one right answer to this question. There will be multiple ways to resolve this. It all depends on your requirements.
I believe that readonly-fields and abstract-getters are two completely different concepts. The readonly-field is all about how the field should be used within the class it is defined in.
An abstract-getter is all about the interface of the class. It does not put any restrictions on how the variable is used, but it forces all class inheritors to implement the getter in order to meet the interface.
The actual question should be where to locate the public getter of the public int Field property; should it be on the base or on the inheriting class? The answer (in my option) depends on whether the base class has to know the actual value of the Field property. If so, place it on the base, otherwise just force all child classes to implement the property getter.
Your abstraction defines a contract that implementors have to comply with. That goes beyond implementing methods with the correct signatures etc. Violating it means breaking the liskov substitution principle, i.e. asking for subtle or not so subtle bugs.
I can understand if someone feels the contract must be enforced somehow, but in the end you cannot enforce complying with LSP. You can only make the intention as clear as possible by using proper documentation and usually unit tests which document behavior as well. And keep in mind that developers usually don't violate contracts or LSP on purpose. If developers have malicious intent, all bets are off anyway.
That being said, I'd say there is no actual difference in the cases you stated. Yes, the implementations are syntactically and semantically different, but other classes would only depend on IFace anyway, right? Seriously, there's no excuse to depend on concrete implementations if there already is an abstraction. So nothing stops anyone from creating a new implementation for IFace and pass that around.

If two class inherit an static field, will the objects of those classes share the same value?

Is it possible that different objects of different classes can use one shared item among themselves (e.g for providing some information on the fly) or better a means of communication between different objects of two different classes ?
Class Base
{
public static string SomeThing = "Shared With All";
}
Class Der1 :Base
{
public void DoSomeThing()
{
SomeThing = "SomeThing Goes in here...";
}
}
Class Der2 :Base
{
public void DoSomeThingElse()
{
Console.WriteLine"(SomeThing);
}
}
....
{
Der1 dr1 = new Der1();
dr1.DoSomeThing();
Der2 dr2 = new Der2();
dr2.DoSomeThingElse(); //shows 'SomeThing Goes in here...'
}
If it helps more, I am trying to create a designer of some kind and so I need to get track of all controls and their associations on the designer. Actually there are only two objects at the moment (one called transaction and the other is called place, different places can be associated with different transactions, and this association is done by the user clicking on one place and pointing to the other transactions (have you seen Proteus? something like that).
So this approach will help me know which object is referring which other object and thus and association between the two can be easily spotted and saved.
The static field isn't really inherited in the same way as normal fields are. There's still just one static field, Base.SomeThing. Both of your derived classes are referring to the same field: if anything changes Base.SomeThing, everything that accesses that field will see the change.
Yep, you've invented a global variable :) It is also almost always a sign of bad design. Try solving your task differently.
It is possible, but think carefully about communicating in this way inside the class. There is no good way to account for concurrency issues and very hard to debug if the value is set multiple places.
You can either use static var's or share stuff using setter and getter. These are basic operators in OOP.
A static field belongs to the class that declares it. Any subclasses of that class gets access to that one static field.
There are some caveats here. Declaring a static variable on a Generic class means that one copy of that variable exists for each closed type of that generic. Here's an example to clarify
public class StaticGenericTest<T>
{
private static int count=0;
public StaticGenericTest()
{
count++;
}
}
If you instantiate a StaticGenericTest<int> and a StaticGenericTest<string> they would have different values for count. However a subclass of StaticGenericTest<int> would share count with all other subclasses of StaticGenericTest<int>.
Also you'll get funny behavior using the ThreadStatic attribute (because you'll get one copy of count per thread) and/or static constructors.
As someone mentioned, Static fields are global state and should be protected as such and used with caution.

Doesn't this defeat the whole purpose of having read-only properties?

I know how to use properties and I understand that they implicitly call underlying get and set accessors, depending on whether we are writing to or reading from a property.
static void Main(string[] args)
{
A a = new A();
(a.b).i = 100;
}
class A
{
private B _b = new B();
public B b
{
get { return _b; }
}
}
class B
{
public int i;
}
What code (a.b).i = 100; essentially does is that first property’s get accessor returns a reference to an object _b, and once we have this reference, we are able to access _b’s members and change their values.
Thus, in our example, having read only property only prevents outside code from changing the value of a reference variable _b, but it doesn’t prevent outside code from accessing _b’s members.
So it seems that property can only detect whether we are trying to read from or write to a variable ( in our case variable _b ) located on the stack, while it’s not able to detect whether we’re trying to also write to members of an object to which the variable on the stack ( assuming this variable is of reference type ) points to.
a) But doesn’t that defeat the whole purpose of having read-only properties? Wouldn’t it be more effective if properties had the ability to also detect whether we’re trying to access members of an object returned by get accessor( assuming backing field is of a reference type )?
thank you
Immutability is not transitive; you can't expect mutable objects into an immutable accessor to be immutable.
Your reference is read only, not your object.
Imagine a class like this:
public class A
{
private List<int> _myList<int> = new List<int>();
public List<int> MyList { get { return _myList; } }
}
Now, users of the class can add and remove and access items in the list, but they cannot replace the list itself. This is important. It allows you to do things inside the class like assume the _myList member is never null, for example.
Put a more general way, this paradigm allows you do define an interface into your class such that users can use the types in the properties you expose, but they cannot just swap instances of complex types out from under you.
No, it does not defeat the purpose of read-only properties.
It is possible to use read-only properties that don't let the user change the underlying data. For example, you can have your property return a System.Collections.ObjectModel.ReadOnlyCollection even though the underlying type is a List. This, of course, won't prevent the user from changing the properties of the items in the collection.
Of course you can access B.i; it's public. You're thinking that since _b is private, all methods should be private when fetched through A? In that case it's pretty useless as you wouldn't be able to use B for anything.
You ask:
Doesn’t that defeat the whole purpose
of having read-only properties?
But look: your B.i member is a public field.
I ask you, then: what is the purpose of having a public field? It only makes sense if you want users of your code to be able to change that field's value. If you don't want that, it should be a private field, or (if you want to provide read but not write access) a property with a private set accessor.
So there's your answer. private B _b serves its purpose in the code you posted quite well (_b cannot be externally set to something new), just as public int i serves its purpose equally well (i can be externally changed).
Reference immutability is a popular feature request. Too bad its is so dramatically non CLS compliant. Very few languages have this notion, I only know of C++ (but don't get out much).
The key problem that this needs to be enforced by the CLR. C++ doesn't need to enforce this at runtime, only a C++ compiler is required to ensure that const contracts are observed. It has no support at all for language interop, beyond a bolt-on like COM.
This won't fly in .NET, there's little point in declaring a reference immutable and have that verified by the compiler when another language can stomp all over it because it doesn't have the syntax to express immutability. I reckon we'll get it some day, not Real Soon.
As a minor point, you don't have to write (a.b).i = 100; but simply
a.b.i = 100;
Back to your question, I don't think it defeats the purpose. You can still not do the following:
a.b = new B();
because there's no public set(). If you want the member i of class B to be read only, you can do the same thing as you did to member _b of class A by making it private and providing a public get(), but not set(). Off the top my head, doing what you propose might lead to many unexpected consistencies (I'm sure the language designers did not overlook this).
Entirely dependent on the situation, but read only access to a mutable object is a commonly used design. In many cases you simply want to ensure that the object itself remains the same.
Some classes (like String object in Java, and I believe in C# as well) are entirely immutable, where as others are only partially mutable. Consider an ActiveRecord style of object for which most fields are mutable, but the ID is immutable. If your class holds an ActiveRecord in a read only property, external classes cannot swap it for a different ActiveRecord object and thus change the ID, which might break assumptions within your class.
I disagree. Your property is for the class B, not for the members of class B. This means you can't assign a new Object to b. It doesn't mean that B's public members suddenly become private.
readonly applies to the class property, not the object that the property refers to. It keeps you from being able to write a.b = new B();, and that is all it does. It places no constraints on what you can do to the object once you get a reference to it. I think what you are discovering is that readonly make the most sense when applied to value types or immutable class types.
Another use case:
interface INamedPerson
{
String Name { get; }
}
class Bob : INamedPerson
{
public String Name { get; set; }
}
class Office
{
// initialisation code....
public INamedPerson TheBoss { get; }
public IEnumerable<INamedPerson> Minions { get; }
}
Now, if you have an instance of the Office, as long as you don't go cheating with casts, you have read-only access to everyone's names, but can't change any of them.
Ah. Encapsulation does the instantiated class inherit the containing class's access level. Exposing type B as a public property of type A. 'B.i' is public so it should be accessible from outside the same way 'A.b' is public.
A.b returns a reference of a privately accessible type B, however type B has a publicly accessible field i. My understanding is that you can set the i field of B but you can't set the b property of A externally. The B type property of A is readonly however the reference to type B does not define the same readonly access to its fields.
I'm sure you can modify the definition of type B to suit your need for the access level of B's fields or properties.

Is it a bad practice to pass "this" as an argument?

I'm currently tempted to write the following:
public class Class1()
{
public Class1()
{
MyProperty = new Class2(this);
}
public Class2 MyProperty { get; private set; }
}
public class Class2()
{
public Class2(Class1 class1)
{
ParentClass1 = class1;
}
public Class1 ParentClass1 { get; set; }
}
Is passing "this" as an argument a sign of a design problem? What would be a better approach?
No, there's no fundamental design problem with passing this. Obviously, this can be misused (creating coupling that's too tight by having a related class depend on values stored in your instance when values of its own would be called for, for example), but there's no general problem with it.
no it is not a problem. THats why 'this' keyword exists, to allow you to pass yourself around
It's hard to say from what you've posted. The question you should ask yourself is: why does class2 need to know about class1? What types of operations is class2 going to perform on class1 during its lifetime, and is there a better way to implement that relationship?
There are valid reasons for doing this, but it depends on the actual classes.
Generally I'd prefer to hand an interface along to the 'child' class, as this reduces coupling. If Class2 really needs access to all of Class1's services and Class2 is public in this way (not fully encapsulated and constructed by Class1), then I'd consider requiring a concrete Class1 instance in the constructor a sign of a possible design issue.
Just to ease your mind a bit:
Passing this as a parameter is even done by classes within the BCL. For example, the List<T>.Enumerator type holds a reference to its parent List<T> object in order to know if the list has been modified between enumerations (and hence when to throw an InvalidOperationException).
This is pretty standard when you've got two (or more) types that actually belong together in a tightly-knit , logically related group (such as the aforementioned collection and enumerator). I've seen plenty of cases where developers bend over backwards to avoid this kind of totally reasonable coupling for no practical reason.
No not a problem, if there is a clear need for a relationship in your design. This pattern is used often in various applications to indicate "parent" or "owner".
I've particularly used it when traversing trees in compiler implementations or in GUI toolkits.
To give an example, check out the visitor pattern:
interface IVisitor {
Visit(SomeClass c);
Visit(AnotherClass c);
}
interface IAcceptVisitor {
void Accept(IVisitor v);
}
public SomeClass : IAcceptVisitor {
void Accept(IVisitor v) {
v.Visit(this);
}
}
I do not know the memory model in C# in detail (at all). But passing this from the constructor to another object is inherently unsafe in many languages (including Java).
If you are in a constructor, the object is not constructed yet. If the other object decides to use the passed this argument at this moment, it would reference an object in an undefined state.
In your example such undefined usage does not happen, but how would you guarantee that it won't in the future? What if somebody subclasses/modifies Class2 in a manner that it uses something from ParentClass1 in its own constructor?

When is it ok to change object state (for instance initialization) on property getter access?

(except for proxy setup!)
I spent some time writing a question here regarding a better pattern for a problem I had - of a class that performed some conditional initialization on almost every property getter, since the initialization in the base class relied on data from the inheriting classes that wasn't available on construction.
While writing the question I came to the conclusion it would be better practice to initialize on inheritor construction. This would require every inheriting class to call the parents initialization method, but I think it's better, because:
I don't have to remember to initialize in the base class on every new property getter/setter.
I don't accidentally trigger the initialization while debugging (see my question here)
If you ever had code that changes state in a property getter, do you think it's absolutely justified? Can you give an example for such a case? (Or even describe the pattern?)
I could only think of proxy access, where you don't want to perform initialization until property access...
Somebody suggested that I initialize using a factory/static method - that's actually a good idea (when the construction is simple, a bit harder when it's not uniform across inheriting classes), but the answer was deleted before I had a chance to submit my reply. too bad.
Lazy caching. Where you dont load the data from the database until the property is accessed. (Not sure if this is what you mean by proxy access).
However, I wouldnt really consider this to be logically changing the state of the object as the behaviour of the class remains the same before and after access. The data is implicitly there at all times. The logical state remains unchanged.
I would never change the logical state of a class through a getter as it is counter intuitive and logically incorrect. You do risk all sorts of unintended consequences..
You could do something like the following :
public class baseone
{
private baseone ()
{
}
public baseone ( string huh )
{
initialise(huh);
}
protected abstract initialise(string stuff);
}
public class niceone : baseone
{
public niceone (string param)
: base(param)
{
}
protected override initialise(string stuff)
{
// do stuff..
}
}
Making the default constructor of the base class private ensures that the required parameters must be passed to initialise the class.

Categories

Resources