I'm currently altering a widely used class to move as much of the expensive initialization from the class constructor into Lazy Initialized properties. Below is an example (in c#):
Before:
public class ClassA
{
public readonly ClassB B;
public void ClassA()
{
B = new ClassB();
}
}
After:
public class ClassA
{
private ClassB _b;
public ClassB B
{
get
{
if (_b == null)
{
_b = new ClassB();
}
return _b;
}
}
}
There are a fair few more of these properties in the class I'm altering, and some are not used in certain contexts (hence the Laziness), but if they are used they're likely to be called repeatedly.
Unfortunately, the properties are often also used inside the class. This means there is a potential for the private variable (_b) to be used directly by a method without it being initialized.
Is there a way to make only the public property (B) available inside the class, or even an alternative method with the same initialized-when-needed?
This is reposted from Programmers (not subjective enough apparently):
https://softwareengineering.stackexchange.com/questions/34270/best-methods-for-lazy-initialization-with-properties
Well, my recommended solution would be to tell your coworker to use the property, not the field. But you could idiot-proof it to some degree like this:
public class ClassA
{
private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());
public ClassB B
{
get
{
return _b.Value;
}
}
}
Now it's pretty hard to screw up.
You could consider pushing the lazy properties into a base class to avoid direct access to the backing variable. Not ideal I know. I've always thought this was something lacking in C# i.e. direct support for lazy properties.
#chibacity posted (and subsequently) deleted [and later undeleted :P] an alternative option using an abstract base class. While it may not be ideal in terms of code distribution it does provide a nice encapsulation removing a lot of code clutter making for a cleaner and more succinct ClassA. For instance, you could consider combining the techniques to achieve both goals:
public class ClassB { /* Class to be lazily instantiated */ }
public abstract class BaseA
{
private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());
public virtual ClassB B { get { return _b.Value; } }
}
public class ClassA : BaseA
{
public override ClassB B { get { return base.B; } }
}
At first glance, it seems like this is more long winded, but when you consider that ClassA which is the class you would be working in and with, this now means that all your references are going through the same property - there is no extraneous unnecessary field causing potential confusion, there's no bypassing the property to reference _b directly and there's no need to tell your coworker which to use... there's only one.
Not saying this is the right way to do this or that this is a pattern that should or shouldn't be followed, I'm just pointing out the advantages of what #chibacity suggested that may otherwise go unnoticed.
It would be nice if you could have implicit lazy loaded properties without having to refer to B.Value... for instance:
[Lazy]
public ClassB B { get; }
or for objects without parameterless constructors
[Lazy(() => new ClassB("Hello", "World"))]
public ClassB B { get; }
or perhaps as #chibacity suggested in a comment
public ClassB B { lazyget; }
or
public ClassB B { lazyget : new ClassB(); }
Alas, I don't think any of these are currently available solutions in any form...
Related
Right now in my code, I have an abstract class, which contains a nested class. In the constructor of every class implementing my abstract class, I will have to construct an instance of the nested class, and pass a reference to the current object to the nested class, as demonstrated below.
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo()
{
this.SpecialStuff = new SpecializedClass(this, "stuff"); // <= This is the issue
// More stuff
}
}
As you can see, whenever I need to call new SpecializedClass(), I have to pass a reference to this. Is there a way to do this automatically, so the classes inheriting from MainClass don't need to keep passing references down?
There answer is basically no. The stack frame does not contain a reference to the calling object (if any), there is no way to get at it fundamentally unless you pass it in, or want to walk the stack (bad idea).
There are however situations where you can use expression trees for more complicated less trivial problems. however, they hardly apply here, and would be more printable characters anyway.
I guess another approach would be an extension methods, however you are just kicking the this ball up the road and creating more code for no good reason
Which leaves with a instance method or base class...
Lastly, although common, I would double check you actually need the calling object. This can easily brush up on design issues such as the Single Responsibility principle (SRP) and Separation of concerns (SOC) among others
All things being equal, if you need it then just pass it in.
No, this is not possible.
Think about it: You could run SpecialStuff = new SpecializedClass(this, "stuff"); in a static function. Then what would the value of this be?
It seems that you could push that functionality into the base abstract class.
Now you only need to call the SpecializedClass and pass this once
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
public MainClass(object stuff)
{
this.SpecialStuff = new SpecializedClass(this, stuff);
}
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo() : base("stuff")
{
// More stuff
}
}
Have some newbie questions.
I have 6 classes:
public class MainSettingsClass
{
int a;
int b;
}
public class SubSettingsClass_1 : MainSettingsClass
{
int c;
}
public class SubSettingsClass_2 : MainSettingsClass
{
int d;
}
public class ParentClass
{
public MainSettingsClass settings;
}
public class ChildClass_1 : ParentClass
{
}
public class ChildClass_2 : ParentClass
{
}
Now the questions. ChildClass_1 with SubSettingsClass_1 and ChildClass_2 with SubSettingsClass_1
ChildClass_1 firstClassVar = new ChildClass_1();
ChildClass_2 secondClassVar = new ChildClass_2();
SubSettingsClass_1 firstClassSettings = new SubSettingsClass_1();
SubSettingsClass_2 secondClassSettings = new SubSettingsClass_2();
firstClassVar.settings = (MainSettingsClass)firstClassSettings;
secondClassVar.settings = (MainSettingsClass)secondClassSettings;
The main thing that if i need get "c" variable using "firstClassVar.settings" i need everytime write:
((firstClassSettings)firstClassVar.settings).c
Is it right way to access variables?
Or there is a better ways exists?
Is this code corresponds programming rules? Or its not correct?
Sorry for bad english.
Is that the "right" way to access the c variable? No. If you have to downcast, at least check it first:
firstClassSettings derivedSettings = firstClassVar.settings as firstClassSettings;
if (derivedSettings != nulL)
{
//Do whatever with derivedSettings.c
}
There's a better way :) Its called polymorphism. Your classes are super general, so its hard to say exactly how your design should look, but your main class should have some method that the derived classes override to get the custom behavior.
Downcasting is a huge code-smell. Sometimes there is no way around it (especially in legacy code, or in certain Object overrides and WPF interfaces) but, you should avoid it if at all possible. Doubly so in your own objects/code.
What you have is technically fine, although there's a few somewhat problematic aspects. First, there's no need to cast to MainSettingsClass. Since both SubSettingsClass_1 and SubSettingsClass_2 inherit from MainSettingsClass, ParentClass, and all derivatives thereof, will accept either as the value for a field defined as being of type MainSettingsClass.
Second, fields (of which settings is one) aren't typically made public. Properties, which have defined getters and setters are generally your interface to data on a object.
Third, settings here is a dependency, and as such, should really be injected via the constructor of the class. Something like:
public class ParentClass
{
protected MainSettingsClass settings;
public ParentClass(MainSettingsClass settings)
{
this.settings = settings;
}
}
UPDATE
One more thing I just thought about that would be beneficial for you to know. Keep in mind that by using a least common denominator like MainSettingsClass, you lose the ability to work with specific members of the more specific derived classes SubSettingsClass_1 and SubSettingsClass_2. However, generics can be used to give you a bit more flexibility:
public class ParentClass<TSettings>
where TSettings : MainSettingsClass
{
protected TSettings settings;
public ParentClass(TSettings settings)
{
this.settings = settings;
}
}
public class ChildClass_1 : ParentClass<SubSettingsClass_1>
{
...
}
public class ChildClass_2 : ParentClass<SubSettingsClass_2>
{
...
}
With that, you can now work with c in ChildClass_1 and d in ChildClass_2 because the type of your settings field will be SubSettingsClass_1 and SubSettingsClass_2, respectively.
I have this construct.
public class SuperClass{}
public class InheritedClass : SuperClass{}
I want my instantiated Superclass to become an InheritedClass instance.
var superClassInstance = new SuperClass();
InheritedClass inHeritInstance = new InheritedClass(superClassInstance) ;
Somebody told me, that will not work without setting all properties in the Constructor.
Is that correct?
I want my instantiated Superclass to become an InheritedClass instance.
This is not possible. If you want it to be an instance of InheritedClass you must create one. You cannot upcast an instance of SuperClass.
That's true.. you can not Assign directly, In Constructor you have to transfer.
Instead..
you should create interface and implement the Interface into the class from where you are passing the value.
Now in into InheritedClass create constructor with the the interface as parameter, so whatever values are assigned into the First class, will be passed into InheritedClass
here you will have full access of First Class property.
Refer below dotnetfiddle url.
http://dotnetfiddle.net/8AgOCF
Yes, that is correct. There is no inbuilt way to provide your own baseclass object to promote to subclass. Each subclass will build it's own baseclass before it calls the subclasses' constructor on it.
You will need to write your own constructor in the subclass that copies all relevant data.
In a sense, yes, I'm afraid that is correct. A constructor is, by definition, creating a new instance. So anything from an existing instance is going to have to be copied to the new instance. It might be something like this:
public InheritedClass(SuperClass superClassInstance)
{
// base fields
Field1 = superClassInstance.Field1;
Field2 = superClassInstance.Field2;
Field3 = superClassInstance.Field3;
// local fields
Field4 = "some value";
// etc.
}
Or you can split the work between the classes, something like this:
public SuperClass(superClassInstance)
{
Field1 = superClassInstance.Field1;
Field2 = superClassInstance.Field2;
Field3 = superClassInstance.Field3;
}
then in the derived class:
public InheritedClass(superClassInstance)
: base(superClassInstance)
{
Field4 = "some value";
// etc.
}
It gets a lot easier the other way around, creating a SuperClass from InheritedClass, since any instance of InheritedClass is an instance of SuperClass and can polymorphically be interpreted as such:
SuperClass someObject = inheritedClassInstance as SuperClass;
(Note that this would not be a "new instance" so watch out for reference errors.) You might be able to do the same in reverse:
InheritedClass someObject = superClassInstance as InheritedClass;
But there is no guarantee that superClassInstance is also an instance of InheritedClass so you'd want to check for errors here. And, again, this is not a new instance.
Using composition instead of inheritance you can potentially achieve your goal with less code. For example, if you have a class like this:
public class InheritedClass
{
public SuperClass BaseObject { get; private set; }
// other fields
}
Then you can include a constructor in InheritedClass which just sets that one object:
public InheritedClass(SuperClass superClassInstance)
{
BaseObject = superClassInstance;
}
Again, however, note that this is not a new instance of SuperClass in the property but a reference to the existing one. To ensure a new one you'd still have to write your manual code (possibly in a .Copy() or .Clone() method on SuperClass?) to duplicate the instance.
In short, after all of my directionless brainstorming, cloning an instance field-by-field is going to require putting that field-by-field code somewhere.
Ok, here (a and b fields are for demo purposes):
public class SuperClass
{
object a;
public SuperClass()
{
a = "123";
}
// you need to have this
public SuperClass(SuperClass copy)
{
a = copy.a;
}
}
public class InheritedClass : SuperClass
{
object b;
public InheritedClass()
{
Init();
}
// and this
public InheritedClass(SuperClass super): base(super)
{
// bacause you can't call base() and this()
Init();
}
private void Init()
{
b = "456";
}
}
So you can do
var super = new SuperClass();
var inherited = new InheritedClass(super);
Proof.
I found a solution, which can at least copy all the properties automatically.
public InheritedClass(SuperClass superClassInstance)
{
foreach(var currentItem in superClassInstance.GetType().GetProperties())
{
GetType().GetProperty(currentItem.Name).SetValue(this,currentItem.GetValue(superClassInstance,null),null);
}
}
This question already has answers here:
Initialize class fields in constructor or at declaration?
(16 answers)
Closed 10 years ago.
I am beginner in object oriented programming and I have one simple question. What is difference between:
public class Calculation
{
private _externalObject = new ExternalClass();
public int FirstParameter {get;set;}
public int SecondParameter {get;set;}
public int ThirdParameter {get;set;}
public int FourthParameter
{
get
{
_externalObject.Calculate(FirstParameter, SecondParameter, ThirdParameter);
}
}
}
and
public class Calculation
{
private _externalObject;
public Calculation()
{
_externalObject = new ExternalClass();
}
public int FirstParameter {get;set;}
public int SecondParameter {get;set;}
public int ThirdParameter {get;set;}
public int FourthParameter
{
get
{
_externalObject.Calculate(FirstParameter, SecondParameter, ThirdParameter);
}
}
}
I want to learn how should I write optimal code.
In this particular case, there isn't any measurable difference.
If, however, you had more than one constructor, you would have to initialize the field in each constructor if you didn't do it directly in the field declaration.
It is more a matter of personal style than anything.
Note on class design and integration - if you have an external dependency like that, good OOP would require you to use DI (Dependency Injection) instead of instantiating the value within the class directly. Constructor injection is a good choice:
private ExternalClass _externalObject;
public Calculation(ExternalClass externalClass)
{
_externalObject = externalClass;
}
The above allows for modification of behaviour without changing the actual class and makes the class more testable.
In this case, those two classes are identical. In fact, for almost all purposes, the two styles of code you used are the same. In general, you will find that most style guides recommend using the field initializers (this is particularly true of static field initializers).
There is one subtle difference, but it's very unlikely that it will ever affect you.
Whenever you initialize class members inline, C# generates code to perform that initialization just before it runs any code in the constructor. In particular, if your constructor calls into a base class constructor. Field initializers are run before the base class constructor is called, while the code in your user-supplied constructor must be run afterward. That is, the following two classes are slightly different:
public class B : A
{
// This happens *before* the base-class constructor.
public ExternalObject external = new ExternalObject();
public B () : base() { }
}
public class C : A
{
public ExternalObject external;
public C () : base()
{
// This happens *after* the base-class constructor.
this.external = new ExternalObject();
}
}
Note that, if you don't provide a default constructor, C# automatically provides one that calls into base() for you, making your class "look like" class B even if you don't explicitly provide the B() constructor.
In practice, the difference is unlikely to matter. You can't actually reference this in your field initializers, so you can't rely on the base class being constructed in either case.
Consider this scenario:
public class Base
{
public int i;
}
public class Sub : Base
{
public void foo() { /* do stuff */}
}
And then I want to, given an instance of Base get an cloned instance of Sub (with i=17 in this case) so that I can call foo in the subclass.
Base b = new Base { i=17 };
Sub s = CloneAndUpcast(b);
s.foo();
However, how can I create CloneAndUpcast?
I am thinking that is should be possible to recursively clone all of Base-members and properties using reflection. But quite some work.
Anyone with better, neater ideas?
PS. The scenario where I am thinking about using this is a set of "simple" classes in a tree-like structure (no cyclic graphs or similar here) and all the classes are simple value holders. The plan is to have a stupid layer holding all values and then an similar set of classes (the subclasses) that actually contains some business-logic the value-holders shouldn't be aware of. Generally bad practice yes. I think it works in this case.
You could use AutoMapper to avoid the tedium of writing the copy constructors.
public class MyClass : MyBase
{
public MyClass(MyBase source)
{
Mapper.Map(source, this);
}
}
and you need to run this once when your application starts up
Mapper.CreateMap<MyBase, MyClass>();
You can download AutoMapper from https://github.com/AutoMapper/AutoMapper
Here's one way (out of many possibilities) that you could do something like you're asking. I'm not sure this is very pretty and can be kind of ugly to debug, but I think it works:
class BaseClass
{
public int i { get; set; }
public BaseClass Clone(BaseClass b)
{
BaseClass clone = new BaseClass();
clone.i = b.i;
return clone;
}
}
class SubClass : BaseClass
{
public int j { get; set; }
public void foo() { Console.WriteLine("in SubClass with value of i = {0}", i.ToString()); }
}
class Program
{
static void Main(string[] args)
{
BaseClass b1 = new BaseClass() { i = 17 };
BaseClass b2 = new BaseClass() { i = 35 };
SubClass sub1 = CloneAndUpcast<SubClass>(b1);
SubClass sub2 = CloneAndUpcast<SubClass>(b2);
sub1.foo();
sub2.foo();
}
static T CloneAndUpcast<T>(BaseClass b) where T : BaseClass, new()
{
T clone = new T();
var members = b.GetType().GetMembers(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < members.Length; i++)
{
if (members[i].MemberType== MemberTypes.Property)
{
clone
.GetType()
.GetProperty(members[i].Name)
.SetValue(clone, b.GetType().GetProperty(members[i].Name).GetValue(b, null), null);
}
}
return clone;
}
}
Basically, as you suggested, you use reflection to iterate through the object's properties (I set i and j as public properties) and set the values accordingly in the cloned object. The key is using generics to tell CloneAndUpcast what type you're dealing with. Once you do that, it's pretty straightforward.
Hope this helps. Good luck!
Per the "Gang of Four" : "Favor composition over inheritance" and this is a perfect reason to do so...
If we have a SuperClass that looks like this:
public class SuperClass : Person
The SuperClass can easily decorate the Person class adding properties not found in Person class.
But what happens if the Superclass decorations are only for the GUI? For example a bool value indicating "Selected". We are still able to get all Persons from the DB in a List but we run into trouble trying to create the Superclass and merge the DB results.
foreach( var person in myPersonList){
var sc = new SuperClass();
sc.Selected = false;
sc=person;
}
The compiler complains because Superclass is not a Person to the compiler it's a Superclass. The only way to fill in the properties of the Person subclass is to iterate and set each one... like this.
SuperClass.Name = Person.Name;
SuperClass.Id = Person.ID;
Pretty tedious indeed. But there's a better way.... Don't make Superclass inherit from Person
public class SuperClass{
public Person ThisPerson {get;set;}
public bool Selected {get;set;}
}
This gives us "Containment" The Superclass now contains a Person class.
Now we can do this:
foreach(var person in MyPersonList){
var sc = new Superclass();
sc.Selected = false;
sc.Person = person;
}
The consumer of this class must now qualify the properties of the Superclass/Person like this...
forach(var sc in MySuperClassList){
var selected = sc.Selected;
var name = sc.Person.Name;
}
The beauty of this is that in the future, you can add any other container you want and it will NOT affect any other containers. You can also morph the Superclass to anything it contains. If each of the contained classes become Interfaces, then that's one step futher down the road.
Well, since b isn't a Sub, we can't "clone" it as one.
If Base has an appropriate combination of constructor and public properties to let a constructor in Sub ensure that its base would therefore have the same state as b, then we could use that.
I think I'd by-pass the whole thing though. If all we care about is that s have the same state in its base as b, and it has not other state that we're going to care about (or else we'd have to be passing it through to the CloneAndUpcast method), then do we need s at all?
A static method could take a Base and we could just use static public void foo(Base bc). We could even define it as an extension method static public void foo(this Base bc) and then code the call as b.foo(). The only thing this won't let us do that CloneAndUpcast() lets us do is access protected members.
Clone is a bad practice and your question is the reason for that (subclass cloning).
In general, you should just use copy cotrs instead and have the subclass accept a parent as a parameter.
public Base(){}
public Base(Base pSource){}
public Sub(){}
public Sub(Base pSource, other parameters...){}
public Sub(Sub pSource){}