"Reflection": Method with "params" does not initialize my custom Objects - c#

I have a custom class from which I create over 200 objects for a Gui.
In my main class with my business logic I want to apply the instantiation of all my objects, attach them to an event handler and set their Name. Instead of doing all this by hand for every object I thought to create a method that takes as parameters a "params" list of my objects. The problem is that this method seems to work out a "copy" of my objects instead the reference of those. What I have so far is:
My object base class:
public class MyObject
{
... // this works
}
My business class now (what works):
public class Logic
{
public MyObject Object001, Object002,... Object200; // note that they are not instantiated yet
public Logic()
{
Object001 = new MyObject();
Object001.Name = nameof(Object001);
Object001.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
Object002 = new MyObject();
Object002.Name = nameof(Object002);
Object002.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
...
Object200 = new MyObject();
Object200.Name = nameof(Object200 );
Object200.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
}
}
My desired business class (what has not worked):
public class Logic
{
public MyObject Object001, Object002,... Object200; // note that they are not instantiated yet
public Logic()
{
InstantiateAllObjects(Object001, Object002, ..., Object200); // here my 200 objects!
}
private void InstantiateAllObjects(params MyObject[] list)
{
for (int i=0; i<list.Length; i++)
{
// if(list[i]==Object001) Console.WriteLine("Object001== null?: " + (Object001 == null)); --> this executes for EVERY object, instead for only Object001!!
MyObject obj = list[i];
obj = new MyObject();
obj.Name = nameof(obj); // why "nameof(list[i])" didn't work?
obj.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
// if (list[i] == Object001) Console.WriteLine("Object001== null?: " + (Object001== null)); --> this executes again for EVERY object AND (Object001== null) is ALWAYS true!!
}
}
}
Can anybody explain me why my method seems not to create my objects?
Thanks in advance for your time and help!
EDIT
In my opinion, the problem seems to be i have to pass a reference to these declared objects in the 'params' list of my method... is it possible? how? I tried to use the modifiers "out" and "ref" near the "params" in the method, but with "params" seems not to be possible...
EDIT2
Following some suggestions I created in my class: logic an object list:
MyObject[] list = new MyObject[] { Object001, Object002, ..., Object200 };
InstantiateAllObjects(ref list);
and modified my method as per private void InstantiateAllObjects(ref MyObject[] list) iterating inside over list[i], but unfortunately with the same wrong result...
and also tried
List<MyObject> list = new List<MyObject>() { Object001, Object002, ..., Object200 };
InstantiateAllObjects(ref list);
and modified my method as per private void InstantiateAllObjects(ref List<MyObject> list) iterating inside over list[i], but unfortunately also with the same wrong result...

Forget about all those Object001, Object002 etc fields. Just use a new List<MyObject>() and add your objects into it inside the for-loop in your InstantiateAllObjects.
public class Logic
{
private readonly List<MyObject> allMyObjects; // note that they still are not instantiated yet
public Logic()
{
cont int amount = 200;
allMyObjects = new List<MyObject>(amount); // reserve space, but all are still null
InstantiateAllObjects(allMyObjects, amount);
}
private void InstantiateAllObjects(List<MyObject> list, int amount)
{
for (int i=0; i<amount; i++)
{
MyObject obj = new MyObject();
obj.Name = "Object" + (i+1).ToString("000");
obj.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
list.Add(obj); // place the newly created object in the list
}
}
}
Your original test if(list[i]==Object001) fires every time, because both list[i] (for every i) and Object001 are null.
Also note that you can have multiple references to one instance of your MyObject (this already happens when you pass the reference as parameter to some method). The fact that one of those is called "Object001" is not important and in fact unknown to the instance. That is why nameof(list[i]) cannot return "Object001".

Another try, based on Hans Kesting'a answer and anna's statement
2) the name of every object will be (very) different one to another,
it is here just that i used the indexes 001...200 to concept the idea,
To avoid any trouble with accessing the fields and to regard what you wrote in the comments, no getter/setter is used and everything is public. Not the best approach but well, compared to handling 200 separate objects...
public class Logic
{
public List<MyObject> MyObjectList;
public List<string> MyObjectNames;
public Logic()
{
var anotherClass = new AnotherClass();
MyObjectNames = new List<string>() {"Object01", "Object02", "Object03"}; // either add your names here...
MyObjectNames.Add("Object04"); // or add additional names this way
//MyObjectNames.AddRange(anotherNameList); // or add another list or use Linq or whatever
MyObjectList = anotherClass.InstantiateAllObjects(MyObjectNames);
}
}
public class AnotherClass
{
public List<MyObject> InstantiateAllObjects(List<string> nameList)
{
var objectList = new List<MyObject>(nameList.Count);
foreach (var name in nameList)
{
objectList.Add(new MyObject(){Name = name});
}
return objectList;
}
}
Does this meet your requirements?
If you prefer a Dictionary, it's similar:
public class Logic
{
public Dictionary<string, MyObject> MyObjectDict;
public List<string> MyObjectNames;
public Logic()
{
var anotherClass = new AnotherClass();
MyObjectNames = new List<string>() { "Object01", "Object02", "Object03" }; // either add your names here...
MyObjectNames.Add("Object04"); // or add additional names this way
//MyObjectNames.AddRange(anotherNameList); // or add another list or use Linq or whatever
MyObjectDict = anotherClass.InstantiateAllObjects(MyObjectNames);
// objects in dict can be accessed directly by their names:
var object01 = MyObjectDict["Object01"];
}
}
// You can access in derived classes or any other classes
public class DerivedLogic : Logic
{
public void SomeFunc()
{
var object01 = MyObjectDict["Object01"];
}
public void SomeOtherFunc(string objectName)
{
var object01 = MyObjectDict[objectName];
}
}
public class AnotherClass
{
public Dictionary<string, MyObject> InstantiateAllObjects(List<string> nameList)
{
var objectList = new Dictionary<string, MyObject>(nameList.Count);
foreach (var name in nameList)
{
// check if object with name does not already exist.
if(!objectList.ContainsKey(name)
{
// For your property changed assignment, you can separate the object creation and DIctionary/List assignment
var obj = new MyObject() { Name = name };
obj.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
objectList.Add(name, obj);
}
// else .... doe something
}
return objectList;
}
}

All of those arguments are being passed by value. You're passing the references, but the InstantiateAllObjects method can't change the values of any of the fields.
Simplifying this a bit, it's a little like having code like this:
string x = "Original value";
// This copies the value of x into the array
string[] array = new string[] { x };
// This changes the array element, but doesn't affect the x variable at all
array[0] = "Different value";
// Still prints "Original value", because x hasn't changed
Console.WriteLine(x);
As noted in comments, using a list is likely to be a much better approach than lots of different fields here.

Use a class (can be the same as the one with the logic) to hold your MyObject Fields, pass it into a function that uses reflection to populate the fields.
// Class with Fields
public class MyObjectCollection
{
public MyObject Object001;
public MyObject ObjTwo;
}
public class Logic
{
// Init logic
public void Initialise(object controls)
{
Type targType = typeof(MyObject);
var t = controls.GetType();
// iterate all fields of type MyObject
foreach(var fi in t.GetFields().Where(f=>f.FieldType == targType))
{
// initialise as required.
var o = new MyObject();
o.Name = fi.Name;
fi.SetValue(controls, o);
}
}
}
If the field name is not enough for the object name you could use Attributes on the fields to direct initialisation.

This should do the job. It is a reflection-based approach and what it does is:
find all public instance fields
use only those whose name contains Object
create a new instance of MyObject and store that in the field
public void InstantiateAllObjects()
{
foreach (FieldInfo field in this.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.Name.Contains("Object")))
{
MyObject obj= new MyObject();
obj.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
field.SetValue(this, obj);
}
}
If you add above method to your Logic class, you can then call it without having to explicitly pass Object001, Object002 etc. to it.
public class Logic
{
public MyObject Object001, Object002, ... Object200;
public Logic()
{
this.InstantiateAllObjects();
}
}
EDIT: Differently named fields
If the fields do not share a common prefix (that is, if they are not all named Object + ...), there are other ways to get the fields:
.Where(x => x.FieldType == typeof(MyObject))
yields only the fields whose type is MyObject.
You could also create an attribute
[AttributeUsage(AttributeTargets.Field)]
public sealed class FieldIWantToSetAttribute : Attribute { }
and apply that to all fields you want to set, e.g.
public class Logic
{
[FieldIWantToSet] public MyObject Object001; // will be set
[FieldIWantToSet] public MyObject Foo; // will be set
public MyObject Bar; // will not be set
}
Then, change the Where to
.Where(x => x.GetCustomAttribute<FieldIWantToSet>() != null)
Please however note that 1. you should definitely use caching. Reflection without caching is expensive, and 2. please overthink your design - why exactly do you feel the need to expose 200 fields for every other class to see?

Related

Automatically generating a UI based on the Class that has been passed

this might be a very basic question but I am cracking my head at this since months.
I want to create a simple UI for creating objects of the class I pass into the UI constructor.
Let say I have 2 classes:
class Test1
{
public static List<Test1> objectList;
public string code;
public string name;
}
class Test2
{
public static List<Test2> objectList;
public string code;
public string name;
public int value;
}
(the static classes would contain all the objects created out of that class)
what I would like to do is to is to create a Code which takes a class as a variable (maybe a generic class?) and based on that creates all the labels and textboxes based on the fields available in the class.
e.g.
public RegisterUI<T> ()
{
Grid grd = new Grid();
DataGrid dg = new DataGrid();
Button saveBtn = new Button();
//Binding the static list of objects to the DataGrid
dg.ItemSource = T.objectList;
//Adding the UI elemnts to the grid
grd.children.add(dg);
grd.children.add(saveBtn);
//Creating for each field in the Class T a lable based on its name and a combobox + binding
foreach(field in T)
{
Lable lbl = new Lable(field.getName);
ComboBox cbx = new ComboBox();
grd.children.add(lbl);
grd.children.add(cbx);
}
}
Is this even possible? I hope I was not to vague with the mockup code, and you can understand what I am heading for.
Any advice would be highly appreciated. Thanks a lot :)
Yes, it's possible. I've done this exact thing for the purpose of automatically creating settings dialogs (I got tired of making a custom form anytime one of my programs had settings that needed modified by the user).
How?
You're going to need to look into "reflection" which provides you a way to interrogate the structure of objects dynamically.
I don't use generics for this, but rather interrogate the Type from within the class.
If I pass in Test1 into my class I get this:
I wish I could supply source code, but alas, it belongs to my employer. I can, however, supply a short snippet to get you started:
Type type = typeof(Test1);
//Get public fields
List<FieldInfo> fieldInfo = type.GetFields().ToList();
//Get private fields. Ensure they are not a backing field.
IEnumerable<FieldInfo> privateFieldInfo = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(f => !f.Name.Contains("k__BackingField"));
//Get public properties
List<PropertyInfo> properties = type.GetProperties().ToList();
//Get private properties
properties.AddRange(type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance));
Hmm, looks like something an old demo might help solve:
Note: I'm using JSONs and NewtonSoft's JSON library for my implementation to read a JSON and build the object / UI from that:
private void LoadConfig()
{
JsonSerializerSettings jss = new JsonSerializerSettings()
{
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate
};
var cfg = ConfigIO.OpenDefault();
ConfigItem ci = JsonConvert.DeserializeObject<ConfigItem>(cfg.Object);
IEnumerable<MemberInfo> atts = ConfigInterOps.GetAttributes(typeof(ConfigItem));
FillForm(ci, atts);
}
private void FillForm(Object referenceObject, IEnumerable<MemberInfo> atts)
{
int location = 5;
foreach (var att in atts)
{
var cfg = new ConfigurationBox(att.Name, referenceObject.GetType()
.GetProperty(att.Name).GetValue(referenceObject, null));
cfg.Name = $"cfg_ {att.Name}";
cfg.Top = 3 * location;
location += 10;
Controls["flowLayoutPanel1"].Controls.Add(cfg);
}
}
A couple classes I made and use that are referenced above:
public static class ConfigInterOps
{
public static IEnumerable<MemberInfo> GetAttributes(Type type)
{
return type.GetMembers()
.Where(x => x.MemberType == MemberTypes.Property ||
x.MemberType == MemberTypes.Field);
}
}
public static class ConfigIO
{
public static void Save(Config cfg)
{
UseDefaultLocation(cfg);
if (!File.Exists(cfg.FileLocation))
{
File.Create(cfg.FileLocation);
}
File.WriteAllText(cfg.FileLocation, JsonConvert.SerializeObject(cfg));
}
private static void UseDefaultLocation(Config cfg)
{
cfg.FileLocation = cfg.FileLocation ?? Path.Combine($"{AppContext.BaseDirectory}", "conf.jobj");
}
public static Config OpenDefault()
{
var cfg = new Config();
UseDefaultLocation(cfg);
return Open(cfg);
}
public static Config Open(Config config)
{
var text = File.ReadAllText(config.FileLocation);
Config openedCfg = JsonConvert.DeserializeObject<Config>(text);
return openedCfg;
}
}
the reference to ConfigurationBox is a custom control:
And after the config is loaded it looks like:
Obviously it is rough, but it should provide all the basics you need to do something similar.

How can I refer to a field of a class as some object, then use that object to obtain the field's value later?

Say I have the following code
public class FooClass
{
public int A { get; set; } = 0;
public int B { get; set; } = 0;
}
public class BarClass
{
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
}
public class MyClass
{
int z = 0;
public FooClass Foo { get; set; } = new FooClass();
public BarClass Bar { get; set; } = new BarClass();
public static void MyMethod()
{
// List of MyClass objects
var myList = Enumerable.Range(1, 10).Select(_ => new MyClass()).ToList();
// Some flags set elsewhere
bool getFooAValues = true;
bool getBarYValues = true;
bool getClassZValues = true;
// Some statements that collects "field referecnes" of MyClass
var classFieldReferenceList = new List<...>();
if (getFooAValues)
classFieldReferenceList.Add(...);
if (getBarYValues)
classFieldReferenceList.Add(...);
if (getClassZValues)
classFieldReferenceList.Add(...);
// For each field reference
classFieldReferenceList.ForEach(classFieldRef =>
{
// For each class
myList.ForEach(myClassInst =>
{
// "Select"/"Apply" the reference to get the field value
var fieldValue = myClassInt.getTheFieldReferenceValue(classFieldRef);
// Do something with field value...
return fieldValue;
});
// Do something with the list of field values...
});
}
}
In this code, specifically in MyMethod, I create a list of MyClass objects. This class has a few fields, some are simply primitive types, some are instances of other classes. How can I refer to or address these fields in the form of some object I can pass around?
For example, I began writing code, akin to the following
public static void MyMethod()
{
// List of MyClass objects
var myList = Enumerable.Range(1, 10).Select(_ => new MyClass()).ToList();
// Some flags set elsewhere
bool getFooAValues = true;
bool getBarYValues = true;
bool getClassZValues = true;
if (getFooAValues)
{
var Avalues = myList.Select(myClassInst => myClassInst.Foo.A);
// Do Action X to list of values
}
if (getBarYValues)
{
var Yvalues = myList.Select(myClassInst => myClassInst.Bar.Y);
// Do Action X to list of values
}
if (getClassZValues)
{
var Zvalues = myList.Select(myClassInst => myClassInst.z);
// Do Action X to list of values
}
}
Where //Do Action X was quite a few lines of code that I would perform to each set of values (Plotting values on a plot, flags represent showing plot line or not). Though, I don't really want duplicate that code for each possible field I could refer/address within MyClass. Thus, I want to refer to a field by some "object" then "apply" that object to an instance of MyClass later to get the value of the field, if that makes sense.
I feel like this might be akin to defining a delegate? Though the delegate would be specific to some class structure?.. Or maybe there is some simple solution I have confused myself out of finding.
You can use Func<MyClass,object> delegate:
var classFieldReferenceList = new List<Func<MyClass,object>>();
if (...)
classFieldReferenceList.Add(m => m.Foo.A);
if (...)
classFieldReferenceList.Add(m => m.Foo.B);
if (...)
classFieldReferenceList.Add(m => m.Bar.X);
if (...)
classFieldReferenceList.Add(m => m.Bar.Y);
This is not ideal because object is used as the most common denominator, but that would be required for a "mixed bag" of types.
In your second example you could get away with a generic method:
private void DoActionsOnSelectedFields<T>(IEnumerable<MyClass> data, Func<MyClass,T> selector) {
foreach (T val in data.Select(selector)) {
... // Perform some common action
}
}

Why isn't my object being updated

I'm doing something wrong because after the loop executed myData still contains objects with blank ids. Why isn't the myData object being updated in the following foreach loop, and how do I fix it?
I thought it could be that I wasn't passing the object by reference, but added a ref keyword and also moved to the main method and I'm still showing the object not being updated.
Additional Information
The user object in the foreach loop is being updated, but the myData list does not reflect the updates I see being applied to the user object.
** Solution **
I was not creating a List but an Enumerable which was pulling the json each time I went through myData in a foreach list. Adding a ToList() fixed my issue.
public class MyData
{
public string ID { get; set; }
public Dictionary<string, string> Properties { get; set; }
}
int index = 0;
// Does not allow me to up, creates an IEnumerable
//IEnumerable<MyData> myData = JObject.Parse(json)["Users"]
// .Select(x => new MyData()
// {
// ID = x["id"].ToString(),
// Properties = x.OfType<JProperty>()
// .ToDictionary(y => y.Name, y => y.Value.ToString())
// });
//Works allows me to update the resulting list.
IEnumerable<MyData> myData = JObject.Parse(json)["Users"]
.Select(x => new MyData()
{
ID = x["id"].ToString(),
Properties = x.OfType<JProperty>()
.ToDictionary(y => y.Name, y => y.Value.ToString())
}).ToList();
foreach (var user in myData) // Also tried myData.ToList()
{
if (string.IsNullOrEmpty(user.ID))
{
user.ID = index.ToString();
user.Properties["id"] = index.ToString();
}
index++;
}
public class MyData
{
public MyData()
{
this.Properties = new Dictionary<string,string>();
}
public string ID { get; set; }
public Dictionary<string, string> Properties { get; set; }
}
public static void Main(string[] args)
{
IEnumerable<MyData> myDataList = new List<MyData>();
int index = 0; // Assuming your starting point is 0
foreach (var obj in myDataList)
{
if (obj != null && string.IsNullOrEmpty(obj.ID))
{
obj.ID = index.ToString();
// Checks if the Properties dictionary has the key "id"
if (obj.Properties.ContainsKey("id"))
{
// If it does, then update it
obj.Properties["id"] = obj.ID;
}
else
{
// Else add it to the dictionary
obj.Properties.Add("id", obj.ID);
}
}
index++;
}
I believe the reason why your objects are not updating because it's probably still referring to the memory block before your objects were changed. Perhaps. The easiest way (that I can think of, there are thousands of smarter programmers than me) is to create a new list and have it contain all of your updated objects.
Edit
I updated the code above with the code that I have. I created a method to set a small amount of objects to test:
private static IEnumerable<MyData> GetMyData()
{
return new List<MyData>()
{
new MyData(),
new MyData() {ID = "2"},
new MyData() {ID = "3"},
new MyData()
};
}
I was able to view my changes and then go through a foreach loop to view my changes. If the ID of the object is Null or Empty, then it steps into the if check and adds the current index to the ID as you know.
Now for my question: Which "id" is blank? The "id" in the dictionary or is it the ID of the model? Are all of your (Model).ID blank? As the updated code of yours, if your dictionary doesn't have "id" as a key, it's going to throw an exception saying it doesn't exist so you will need to do a check to make sure it does exist or add it if it doesn't.

How to bind object's property to another object's property? (C#)

I'm making a graphic control class Info which should display some text on screen. The text is some object's string. I'd like to be able to get that object's latest value from within an instance of Info class.
class Info
{
public string Text;
}
void Program()
{
ClassA obj = new ClassA();
obj.name = "Instance of ClassA";
Info wind1 = new Info();
wind1.Text = obj.name; // this just copies current value, but should be a reference or something
/* obj.name value changes several times before it's time to display it again */
// Info window drawing method
foreach (var item in Windows) // Windows is List<Info>
Draw(item.Text); // this doesn't get the latest value
}
How should I change the code so I can get the latest string value from within the drawing section?
Update: If you need something that'll work for any type, you'll have to use delegates. For example:
class Info
{
private Func<string> getText;
public Info(Func<string> getText)
{
getText = getText;
}
public string Text
{
get
{
return getText();
}
}
}
void Program
{
ClassA obj = new ClassA();
obj.name = "Instance of ClassA";
Info wind1 = new Info(() => obj.name);
// Now do your stuff.
}
In this case, Info is given an anonymous function that returns a string. When you access its Text property, the function is evaluated to retrieve that string. How the string is retrieved, and where it comes from, is determined by the client code (i.e. the Program method). This way, Info doesn't rely on any particular type.
You could pass the ClassA object into your Info instance, so that it can get the value of.name itself.
Something like this, perhaps?
class Info
{
public Info(ClassA obj)
{
TheObject = obj;
}
public ClassA TheObject
{
get;
set;
}
public string Text
{
get
{
return TheObject.name;
}
}
}
void Program
{
ClassA obj = new ClassA();
obj.name = "Instance of ClassA";
Info wind1 = new Info(obj);
// Now do your stuff.
}

C# - Passing concrete constructor method to create 'child' classes

I have a Class X wich uses a Class Y. The X creates the Y, but X must create Y with THE SAME constructor method was used to create instance-Y passed to X.
It is not a Clone, because I want a NEW object-Y not equals to values of instance-Y passed to X.
It is not a instance because I do not want the SAME object-Y what is pased as instance-Y to X.
I would like to pass the "constructor method and parameters" of class Y to class X and, with this information, create the new Y-instance using the ctor-method-passed.
And I don't want to devel all 'Class Y' constructor logic because, in this case both of them will be very highly coupled.
I have done a little spike to explain myself a bit better.
Thanks.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TheSon son1 = new TheSon();
son1.TheValue = "Another Value";
TheFather<TheSon> father1 = new TheFather<TheSon>(son1);
Console.WriteLine("Result is {0}:", "Empty constructor".Equals(father1.MySon.TheValue));
Console.WriteLine("\tbecause prop. must be: '{0}' and it is: '{1}'", "Empty constructor", father1.MySon.TheValue);
}
public class TheFather<T> where T: TheSon
{
public TheSon MySon { get; set; }
public TheFather(T mySon) {
// I would like to NOT use the same object but
// use the constructor that was used to build the passed object-instance.
//
// Or perhaps pass a concrete TheSon constructor to the 'TheFather'...
this.MySon = (TheSon)mySon;
}
}
public class TheSon
{
public string TheValue { get; set; }
public TheSon()
{
this.TheValue = "Empty constructor";
}
public TheSon(string value)
{
this.TheValue = value;
}
public TheSon(string value, int element)
{
this.TheValue = value + "-> " + Convert.ToString(element);
}
}
}
}
=========SOLUTION:
Adding this constructor to the TheFather class:
public TheFather(Func<T> sonFactory)
{
this.MySon = (T)sonFactory();
}
And with this example:
static void Main(string[] args)
{
// Uncomment one of this to change behaviour....
//Func<TheSon> factory = () => new TheSon();
Func<TheSon> factory = () => new TheSon("AValue");
//Func<TheSon> factory = () => new TheSon("AValue", 1);
TheFather<TheSon> father1 = new TheFather<TheSon>(factory);
Console.WriteLine("Result is {0}:", "AValue".Equals(father1.MySon.TheValue));
Console.WriteLine("\tbecause prop. must be: '{0}' and it is: '{1}'", "AValue", father1.MySon.TheValue);
}
Works like a charm.... :-)
Thanks...
You can simply use a factory to create TheSon objects:
Func<TheSon> factory = () => new TheSon(); // creates one with default ctor
This way you can get a new object each time, but created in exactly the same way (this is not limited to a constructor; you can also include any additional code you want). Use it like this:
var oneSon = factory(); // creates one son
var secondSon = factory(); // creates another with the same constructor
var father = new TheFather(factory()); // ditto
Update: You can also change TheFather's constructor to accept a factory if you want to create TheSon inside TheFather. For example:
public TheFather(Func<T> sonFactory) {
this.MySon = (TheSon)sonFactory();
}
and
var father = new TheFather(factory);

Categories