Accessing a field of outer class from inner class - c#

I have an inner class to contain methods of my project; and I want to use the Form class event handlers to call my methods from the inner class; but I am having trouble accessing members of the outer class such as label1, label2, label3 etc.
How do I access a field of an outer class?
I'm trying to make an association inside the constructor :
public partial class Form1 : Form
{
// declare inner class here
public MachineClass machineObj = new MachineClass();
public class MachineClass
{
int fruit1, fruit2, fruit3, fruitvalue1, fruitvalue2, fruitvalue3;
public void spinslot()
{
Random player = new Random();
fruit1 = player.Next(10);//generates a number between 0 and 9
fruit2 = player.Next(10);//generates a number between 0 and 9
fruit3 = player.Next(10);//generates a number between 0 and 9
fruitvalue1 = fruit1 + 1;//
fruitvalue2 = fruit2 + 1;//
fruitvalue3 = fruit3 + 1;//
label1.ImageIndex = fruit1;//display image in label - uses image list
label2.ImageIndex = fruit2;//display image in label - uses image list
label3.ImageIndex = fruit3;//display image in label - uses image list
}
}
}

One way, off the top of my head, to do this, would be for the parent class to keep reference to the child, and vice versa. So for this class structure:
class ParentClass
{
public ParentClass()
{
this.child = new ChildClass(this);
}
public ChildClass child { get; set; }
class ChildClass
{
public ParentClass Parent { get; set; }
public ChildClass(ParentClass par)
{
this.Parent = parent;
}
}
}
then any time you wanted to access a field in the parent class from the subclass, you could just call .Parent.Whatever. Granted, this forces you to instantiate both at the same time, so I'm not sure if it's that great a way of accomplishing what you intend, nor whether it'll work for your purposes.
Edit: Alternately, you could use ParentClass as a factory of sorts for ChildClass, like so:
class ParentClass
{
public ParentClass() { }
public class ChildClass
{
public ParentClass Parent { get; set; }
public ChildClass(ParentClass par)
{
this.Parent = par;
}
}
public ChildClass GetChild()
{
return new ChildClass(this);
}
}
and you could instantiate an unlimited number of related ChildClasses from any given ParentClass, and calling .Parent from any ChildClass would refer to the ParentClass from which it was created.
I'd like to make a note, though, that in my experience I've found very few uses for inner classes, and I can't think of a single time where the above class designs would have benefited me. Particularly given that your example doesn't really seem like it's doing anything special, it seems like you'd be better off constructing a normal class outside the scope of your Form class and passing data to it as needed, rather than trying to create a convoluted inner class with a parent/child relation.

Here is what you really need to do to make this work and to do so with a better OO design.
First-up, define the internal MachineClass like this:
public class MachineClass
{
private int fruit1, fruit2, fruit3;
public delegate void FruitUpdate(int value);
public event FruitUpdate FruitUpdate1;
public event FruitUpdate FruitUpdate2;
public event FruitUpdate FruitUpdate3;
public void spinslot()
{
Random player = new Random();
fruit1 = player.Next(10);
fruit2 = player.Next(10);
fruit3 = player.Next(10);
if (this.FruitUpdate1 != null) this.FruitUpdate1(fruit1);
if (this.FruitUpdate2 != null) this.FruitUpdate2(fruit2);
if (this.FruitUpdate3 != null) this.FruitUpdate3(fruit3);
}
}
The FruitUpdate delegate allows the definition of three events that can let external users of this class know when updates to the fruit values occur. When updates to the fruit values occur we check that there are handlers attached to the event and then just call the events. The MachineClass does not need to know that there is anything listening.
Now the Form1 class looks a bit like this:
public partial class Form1
{
public MachineClass machineObj = new MachineClass();
public void Form1_Load()
{
this.machineObj.FruitUpdate1 += v => label1.ImageIndex = v;
this.machineObj.FruitUpdate2 += v => label2.ImageIndex = v;
this.machineObj.FruitUpdate3 += v => label3.ImageIndex = v;
}
public class MachineClass
{
/* definition from above */
}
}
Here the Form1 class creates the instance of MachineClass and then attaches handlers to each of the fruit update events. This allows the labels to be updated without the MachineClass being aware of them at all!

Related

Recursive constraints: What does DBase<T> : where T : DBase<T> mean?

I thought I understood generic constraints until I ran across this.
public class DBase<T> : DbContext, IDisposable where T : DBase<T>
How can T be DBase<T>?
And if it can, what does it mean?
This code compiles and runs fine. I'm not fixing a problem. I just don't understand it.
It is used here
public class ChildDb : DBase<ChildDb>
Which, again, doesn't compute for me. It passes itself as a type parameter?
How can T be DBase<T>?
There is no limitation that prevents a Generic Parameter from deriving from itself. While it's not directly understandable with the example you've given. What about a Vertex / Vertice?
Excerpt from Wikipedia:
In geometry, a vertex (plural: vertices or vertexes) is a point where two or more curves, lines, or edges meet. As a consequence of this definition, the point where two lines meet to form an angle and the corners of polygons and polyhedra are vertices.1
How does one describe a Vertex (a point)?
// very simplified example
public class Vertex
{
public int X { get; set; }
public int Y { get; set; }
}
Now how do we add a collection of relationed Verticies to this class but only allow things that derive from this class?
public class Vertex<TVertex> : Vertex
where TVertex : Vertex<TVertex>
{
public IEnumerable<TVertex> Vertices { get; set; }
}
It a generic version of say:
public Vertex2
{
public IENumerable<Vertex2> Vertices { get; set; }
}
However when I derive from Vertex2, my Vertices will always have to be IEnumerable<Vertex2>, and the correct way to allow Vertices to be a derived class is to use this type of self-reference generic.
I'm sorry Erik, I lost the point in the details. What have I gained by the recursion?
Using Vertex2, our derived types lose access to other derived properties:
public class MyVertex2: Vertex2
{
public int Id { get; set; }
}
so
var a = new MyVertex2 {Id = 1 };
var b = new MyVertex2 { Id = 2 };
a.Vertices = new List<Vertex2> { b };
b.Vertices = new List<Vertex2> { a };
// can't access Id because it's a Vertex2 not a MyVertex2
var bId = a.Vertices.First().Id;
Sure you could cast it, but then you're casting it everywhere (that's not DRY)... and what if it's not a MyVertex (MullReferencesException or InvalidCastException).
public class MyVertex: Vertex<MyVertex>
{
public int Id { get; set; }
}
var a = new MyVertex {Id = 1 };
var b = new MyVertex { Id = 2 };
a.Vertices = new List<MyVertex > { b };
b.Vertices = new List<MyVertex > { a };
var bId = a.Vertices.First().Id;
// or even
var aId = a.Vertices.First().Vertices.First();
each time we navigate to a vertices we get the correct derived type, not the base class.
John Wu posted a great blog in the comments, the TLDR of which is:
This code pattern allows you to declare a superclass that must be extended (possibly not by you, if you're writing a library that other people will use) in order to be used, but can have a bunch of methods/signatures (written by you) that return T when you write them but in practice will return objects of the child type (not written by you/you cannot know) so they can be used in a chained fashion (like the way most StringBuilder methods return the StringBuilder itself so the user can call .Append().AppendLine() ) without needing to be cast (in the code not written by you) from the parent type (written by you) to the child type (not written by you)
There's a caveat: it's not particularly useful because only the deepest child in an inheritance tree can be instantiated. Avoid using it
As a useful example, it allows you to have some methods or properties in the base class which return derived type.
For example, in the fluent builders which have chainable methods, let's say we have a base builder which set some common properties. What should be the output type of these methods?
See the following example:
public abstract class Control
{
public string Id { get; set; }
}
public abstract class ControlBuilder<TBuilder, TControl>
where TBuilder : ControlBuilder<TBuilder, TControl>, new()
where TControl : Control, new()
{
protected TControl control;
protected ControlBuilder()
{
control = new TControl();
}
public static TBuilder With()
{
return new TBuilder();
}
public TControl Build()
{
control;
}
public TBuilder Id(string id)
{
control.Id = id;
return (TBuilder)this;
}
}
Without having ControlBuilder<TBuilder, TControl> as a constraint for TBuilder, how you can return a TBuilder from Id method?
If you say ask why not return ControlBuilder<TBuilder, TControl>, because if you return it, after calling .Id("something") in method chains, it will not show derived class methods and it just will show methods of ControlBuilder<TBuilder, TControl>.
Let's say we create a TextBoxBuilder for building a TextBox:
public class TextBox : Control
{
public string Text { get; set; }
}
public class TextBoxBuilder : ControlBuilder<TextBoxBuilder, TextBox>
{
public TextBoxBuilder Text(string text)
{
control.Text = text;
return this;
}
}
Now we can use it as expected:
var txt = TextBoxBuilder.With().Id("textBox1").Text("Hello!").Build();

Handling the interacton of intances of classes belong to two parallel inhertiance groups

I have two groups of classes in my code and one group has logic and other group has data and inheritance is also being used in each group. I tried to mimic the situation which I am dealing with in below code snippet. The problem I have is how to handle the objects of derived data classes efficiently in related instances of logic classes. Right now I am trying to cast the instance of derived data class in a method of derived logic class which I do not think is logical. I need some guidance to address this issue.
void Main()
{
var item1 = new D1();
var holder1 = new DataHolder1() { localProp1 = "test" };
var holderout = item1.Method1(holder1);
holderout.Dump();
}
public class BaseDataHolder
{
public string prop { get; set; }
}
public class DataHolder1 : BaseDataHolder
{
public string localProp1 { get; set; }
}
public class DataHolder2 : BaseDataHolder
{
public string localProp2 { get; set; }
}
public class BaseClass
{
public virtual BaseDataHolder Method1(BaseDataHolder holder)
{
return null;
}
}
public class D1 : BaseClass
{
public override BaseDataHolder Method1(BaseDataHolder holder)
{
(holder as DataHolder1).localProp1.Dump();
(holder as DataHolder1).localProp1 = "change1";
return holder;
}
}
public class D2 : BaseClass
{
public override BaseDataHolder Method1(BaseDataHolder holder)
{
(holder as DataHolder2).localProp2.Dump();
(holder as DataHolder2).localProp2 = "change2";
return holder;
}
}
I don't see why it would be illogical since looks like you are trying to get DataHolder1 always in class D1. Rather, why can't your class compose with Data class instance and use that in method like
public class D1 : BaseClass
{
private readonly DataHolder1 holder;
public D1(DataHolder1 holder) { this.holder = holder; }
public override BaseDataHolder Method1()
{
holder.localProp1.Dump();
holder.localProp1 = "change1";
return holder;
}
}
Then you can just say
var item1 = new D1(new DataHolder1());
BaseDataHolder data = item1.Method1();
This violates the Liskov substitution principle. In summary, it's bad, because your signature promises to work well with any BaseDataHolder but in reality it will just crash if the wrong BaseDataHolder is passed in.
I cannot really give a solution because we don't know your requirements. From what you have posted, your three logic classes should drop the inheritance and just have three different method signatures, each telling what it needs instead of all of them lying about what they need and then crashing randomly.

How to get the name of class where an object is initialized c#

I have a few classes. Lets say:
public class A
{
public void SomeAction()
{
Debug.Write("I was declared in class: and my name is:");
}
}
And
public class B
{
public static A myClass = new A();
}
public class C
{
public static A myClass = new A();
}
public class D
{
public static A myClass = new A();
}
What I want "SomeAction" in class A to do is to print out which class it was initialized in.
So that for example in another class I called C.myClass.SomeAction(); it would print out "I was declared in class C my name is myClass"
I hope this makes sense.
The reasons im doing this is for debugging within automated testing. I understand its not the best way to do things but its a requirement of the business.
This requirement can be satisfied without inheritance or passing the object; we can get the name of the class that calls the constructor from within the body of the constructor by examining the stack.
public class A
{
private string _createdBy;
public void SomeAction()
{
Console.WriteLine("I was declared in class [{0}]", _createdBy);
}
public A()
{
var stackFrame = new StackFrame(1);
var method = stackFrame.GetMethod();
_createdBy = method.DeclaringType.Name;
}
}
In terms of performance, I am assuming that you are not creating many instances of these objects. You could also predicate this on whether you are doing a DEBUG build or on some other setting, so that this stuff is skipped entirely in your production executables.
Since you only reference an instance of class A in your other classes, I think there is no other way then setting a reference to the type which created class A, like eddie_cat already mentioned. You could do something like this:
public class B
{
public static A myClass = new A(typeof(B));
}
And then your class A would look like:
public class A
{
// store the parent type
private Type mParentClass;
// provide parent type during construction of A
public A(Type parentClass)
{
mParentClass = parentClass;
}
// note that method cannot be static anymore, since every instance of A might
// have a different parent
public void SomeAction()
{
// access field where parent type is stored.
Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
}
}
I think you have two choices. Either set a property in A, or inherit from A. Personally, I prefer inheriting from A, because then A could just use GetType().
public class A
{
public void SomeMethod()
{
Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
}
}
public class B : A
{
}
var instanceOfB = new B();
instanceOfB.SomeMethod();

Class inheritance & constructors

Hello to all the brilliant minds of StackOverflow!
I am getting familiar with c# class inheritance and multiple constructors but I can't seem to word a question that would allow me to Google it.
Here's what I have:
public class Order: OtherOrder
{
private OtherOrderManager _om;
public Order()
{
if (_om == null)
_om = new OtherOrderManager();
}
public Order(int orderID)
: base()
{
}
}
So obviously, now I can do something like:
Order order = new Order();
order.Member_From_OtherOrder_Class = "bleh";
But here's what I'm trying to implement in a constructor:
public class Order: OtherOrder
{
private OtherOrderManager _om;
public Order()
{
if (_om == null)
_om = new OtherOrderManager();
}
public Order(int orderID)
: base()
{
this = (Order)_om.GetOrder(orderID); //Returns an instance of OtherOrder
//Basically, I want to populate all the members of Order() interited
//from OtherOrder and fill them with data returned by this call.
}
}
Obviously, "this" is read only so that doesn't even compile. Is there any technical expression that would describe what I'm looking for ? Is it even possible ?
Thanks!
EDIT: I think I'll use reflection to loop through all members and get/set values this way.
Even though it's a bit vague about what you're trying to achieve, I'm guessing you might want to use something along the lines of using a factory possibly with copy-constructors. Essentially, the copy-constructors provide an easy means to populate data along the inheritance chain with your copies.
Consider the following base class:
public abstract class OrderBase
{
public int OrderID { get; private set; }
public string Name { get; protected set; }
public OrderBase()
{
}
public OrderBase(OrderBase copiedOrder)
{
this.OrderID = copiedOrder.OrderID;
this.Name = copiedOrder.Name;
}
}
(I left the parameterless constructor in there because I'm guessing it will be needed somewhere)
So an OrderBase can be instantiated by passing another OrderBase instance. Within that constructor, we know which properties to copy over and are compile-time checked.
Now a subclass might be:
public class CustomOrder : OrderBase
{
public Guid CustomID { get; private set; }
public CustomOrder()
{
}
public CustomOrder(CustomOrder copiedOrder)
: base(copiedOrder)
{
this.CustomID = copiedOrder.CustomID;
}
}
Here, the CustomOrder only copies its own property that is declared on it and passes the rest of the copying responsibility to the base class. Add one more class to the chain:
public class ValidatableCustomOrder : CustomOrder
{
public bool IsValid { get; private set; }
public ValidatableCustomOrder()
{
}
public ValidatableCustomOrder(ValidatableCustomOrder copiedOrder)
: base(copiedOrder)
{
this.IsValid = copiedOrder.IsValid;
}
}
And you can see how it can nicely manage each property set per subclass without any one class knowing much about the other. Your factory in turn might look something like:
public static class ValidatableCustomOrderLoader
{
public static ValidatableCustomOrder Get(int orderID)
{
ValidatableCustomOrder loadedOrder = LoadOrderFromSomewhere(orderID);
ValidatableCustomOrder copiedOrder = new ValidatableCustomOrder(loadedOrder);
return copiedOrder
}
private ValidatableCustomOrder LoadOrderFromSomewhere(int orderID)
{
//get your order somehow
}
}
So it (somehow) loads the data (perhaps from a database), copies it to a new instance which will chain through all the copy-constructors. Your calling code would look like:
int orderID = 10;
ValidatableCustomOrder order = ValidatableCustomOrderLoader.Get(orderID);
Anyhow, I can't say if this will specifically help you since your question/code seems a bit off-the-wall and vague, but hopefully it will help give you some ideas.
Two approaches come to mind: manually copy the properties:
public Order(int orderID)
: base()
{
var other = (Order)_om.GetOrder(orderID);
this.SomeProperty = other.SomeProperty; //repeat for each property/field that should be copied
}
Or use a static or factory method instead of constructors, e.g.:
public static Order GetOrder(int orderId)
{
return (Order)_om.GetOrder(orderID);
}
Try:
this._om = (Order)_om.GetOrder(orderID);
Hope that helps.

Dynamically add a Property to a System.object?

I got a list of different objects that I defined in different classes and I'd like to add a string property "Name" to all these objects. Is that possible ?
I don't have that much code to provide as my classes are very simple/classic ones.
Thanks in advance for any help !
(edit : I don't want to inherit from an abstract class that adds this property ! In fact, I don't want to modify at all my class that define my object. That's what i call "Dynamically" in the title.
What I want is something like :
myObject.AddProperty(string, "Name");
or
myObject.AddAttribute(string, "Name");
(I don't know how it is exactly called)
and then I can do :
myObject.Name = "blaaa";
Create an abstract class that all of your other classes could inherit:
public abstract class MyBaseClass
{
public string MyCommonString { get; set; }
}
public class Foo : MyBaseClass
{
public MyBaseClass() { }
}
//Create instance of foo
Foo myFoo = new Foo();
//MyCommonString is accessible since you inherited from base
string commonString = myFoo.MyCommonString;
EDIT (per new requirement)
Since you don't want to touch the original classes in the DLL, I'd take this [similar] approach:
public abstract class MyBaseClass
{
public string MyCommonString { get; set; }
}
//This class definition lives in the DLL and remains untouched
public class Foo
{
public Foo() { }
}
//This partial class definition lives in [insert new project name here]
public partial class Foo : MyBaseClass
{
public Foo () { }
}
Notice that Foo is now a partial class. You're not touching the existing class definition in the DLL, you're extending it.
EDIT (per newer new requirement)
Given your requirements (no editing of original class), what you're asking is not possible.
What you can do is to hard code a Hashtable named CustomProperties
Now you can fill this Hashtable with custom properties
Something like that:
MyClass myClass = new MyClass();
myClass.SetProperty("abc", 123);
myClass.SetProperty("bcd", "bla");
myClass.SetProperty("cde", DateTime.Now);
MessageBox.Show(myClass.GetProperty("abc").ToString());
class MyClass
{
private Hashtable MyProperties { get; set; }
public MyClass()
{
MyProperties = new Hashtable();
}
public object GetProperty(string name)
{
return MyProperties.Contains(name) ? MyProperties[name] : null;
}
public void SetProperty(string name, object value)
{
if (MyProperties.Contains(name))
MyProperties[name] = value;
else
MyProperties.Add(name, value);
}
}
You want to use the new C# 4.0 dynamic keyword:
dynamic obj = new System.Dynamic.ExpandoObject();
obj.Value = 10;
var action = new Action<string>((l) => Console.WriteLine(l));
obj.WriteNow = action;
obj.WriteNow(obj.Value.ToString());
You can not do this with object, but the ExpandoObject will do just fine.
But... overuse dynamic typing and you'll find yourself in a maintenance nightmare in the near future.

Categories

Resources