Considering the following scheme.
A class that contains an object, in this case I'm using OriginObject
.
The main problem is that the property NestedName has to access instructions about its behavior from another property within the OriginObject, in that case I thought about using reflection but, it's getting really confused.
The problem:
public class OriginObject
{
public NestedObject nestedObject { get; set; }
public Instructions Instruct { get; set; }
public class NestedObject
{
public string NestedName { get; set; }
public void GetName()
{
NestedName = //this.instruct.Name? being "this" the OriginObject;
}
}
public struct Instructions
{
public string Name { get; set; }
}
}
public void GetName()
{
NestedName = GetType().DeclaringType
.GetProperty("instruct")
.GetValue(GetType().DeclaringType)
.GetType()
.GetProperty("Name")
.GetValue(wtf im doing);
}
I know I can simply add a parameter that provides me the Origin Object but, in my logical base knowledge this means Clean and beautiful code:
/Target.DoSomething( );
/
or in production terms speaking it will be something like
Body.Parse( );
Does somebody know any other way to do this? Without creating an ilegal crime of sequential methods?
If it's just a bad idea I can change it.
CodePudding user response:
I understand that this is some code that you're just playing around with and that you're not really looking at having three classes to encapsulate one string...
With your code as it is, an instance of OriginObject.NestedObject
does not hold onto a reference to an instance of OriginObject
.
Having your classes nested is nice if you want to be able to access nonpublic members (methods, etc.) but everything in your code is public so there's no benefit there.
As there's no coupling (OriginObject.NestedObject
and OriginObject.Instructions
don't access any methods or static members on OriginObject
) your code is equivalent to how they would be if there was no nesting.
You can probably see why your code won't work if you rewrite NestedObject
and Instructions
to not nested - you'd have this equivalent code:
public class OriginObject
{
public NestedObject nestedObject { get; set; }
public Instructions Instruct { get; set; }
}
public class NestedObject
{
public string NestedName { get; set; }
public void GetName()
{
NestedName = // How is NestedObject supposed to get anything from OriginObject?
}
}
public struct Instructions
{
public string Name { get; set; }
}
One fix would be to pass in an instance of OriginObject
to a constructor of NestedObject
, e.g.
public class OriginObject
{
public NestedObject Nested { get; set; }
public Instructions Instruct { get; set; }
public class NestedObject
{
private OriginObject _origin;
public NestedObject(OriginObject origin)
{
_origin = origin;
}
public string NestedName
{
get; set;
}
public void GetName()
{
NestedName = _origin.Instruct.Name;
}
}
public struct Instructions
{
public string Name { get; set; }
}
}
You'd then do something like this:
var instructions = new OriginObject.Instructions() { Name = "Test" };
var origin = new OriginObject() { Instruct = instructions };
var nested = new OriginObject.NestedObject(origin);
nested.GetName();
That was a bit clunky though - you have to pass in the OriginObject
to the OriginObject.NestedObject
, but you only ever use it to access the Instructions
property. It'd be better if you just passed the Instructions
object directly into the constructor, e.g.:
public class OriginObject
{
public NestedObject Nested { get; set; }
public Instructions Instruct { get; set; }
public class NestedObject
{
private Instructions _instructions;
public NestedObject(Instructions instructions)
{
_instructions = instructions;
}
public string NestedName
{
get; set;
}
public void GetName()
{
NestedName = _instructions.Name;
}
}
public struct Instructions
{
public string Name { get; set; }
}
}
which you'd use with something like this:
var instructions = new OriginObject.Instructions() { Name = "Test" };
var origin = new OriginObject() { Instruct = instructions };
var nested = new OriginObject.NestedObject(instructions);
nested.GetName();
Now, it's a bit weird to have a GetName()
method that you have to call each time and doesn't return anything. Better still might be to get rid of the GetName()
method and have the NestedName
property a computed property instead:
public class OriginObject
{
public NestedObject Nested { get; set; }
public Instructions Instruct { get; set; }
public class NestedObject
{
private Instructions _instructions;
public NestedObject(Instructions instructions)
{
_instructions = instructions;
}
public string NestedName
{
get
{
return _instructions.Name;
}
}
}
public struct Instructions
{
public string Name { get; set; }
}
}
You'd then call that with an arguably simpler bit of code:
var instructions = new OriginObject.Instructions() { Name = "Test" };
var origin = new OriginObject() { Instruct = instructions };
var nested = new OriginObject.NestedObject(instructions);
At this point you might as well have a constructor for OriginObject
too, so you know that the Instructions
and the NestedObject
instances are set - you could have something like this:
public class OriginObject
{
public NestedObject Nested { get; set; }
public Instructions Instruct { get; set; }
public OriginObject(NestedObject nested, Instructions instruct)
{
Nested = nested;
Instruct = instruct;
}
public class NestedObject
{
private Instructions _instructions;
public NestedObject(Instructions instructions)
{
_instructions = instructions;
}
public string NestedName
{
get
{
return _instructions.Name;
}
}
}
public struct Instructions
{
public string Name { get; set; }
}
}
which you'd use with some code like this:
var instructions = new OriginObject.Instructions() { Name = "Test" };
var nested = new OriginObject.NestedObject(instructions);
var origin = new OriginObject(nested, instructions);
Note that there's still no need for any nested types: you could have this equivalent code without nesting:
public class OriginObject
{
public NestedObject Nested { get; set; }
public Instructions Instruct { get; set; }
public OriginObject(NestedObject nested, Instructions instruct)
{
Nested = nested;
Instruct = instruct;
}
}
public class NestedObject
{
private Instructions _instructions;
public NestedObject(Instructions instructions)
{
_instructions = instructions;
}
public string NestedName
{
get
{
return _instructions.Name;
}
}
}
public struct Instructions
{
public string Name { get; set; }
}
which would be called with code like the following:
var instructions = new Instructions() { Name = "Test" };
var nested = new NestedObject(instructions);
var origin = new OriginObject(nested, instructions);