C# - Pass a struct to a form by reference and return value? - winforms

I have a struct:
struct Order
{
public string orderNumber;
public string orderDetail;
}
I then assign some values in Form1 and try to pass them by reference (ref) to Form2:
(Form1)
Order order = new Order();
order.orderNumber = "1234";
order.orderDetail = "Widgets";
Form2 frm2 = new Form2(ref order);
Is it possible to store the values in Form2 so that when Form2 is completed processing the values it will return the updated struct values to Form1?
In this scenario there would be a button that would close the form after validating the data.

One pattern that's sometimes useful is to define a class something like:
class Holder<T> {public T value;}
Such a class makes it possible to pass and mutate value types with code that requires reference types. Using such an approach, a routine which accepted a structure by reference and was supposed to pop up a modal dialog and fill in the structure from it, could create a Holder<thatStructType>, pass that to the form, and then copy the data from that Holder back to the passed-in reference. While in your particular scenario, it may be better to have the data-holding thing simply be a class, structures have the advantage that one can know that no outstanding references to them exist; if a routine declares a structure and passes it by reference to some outside code, then once that code returns the values in that structure won't change unless or until the routine writes them itself or passes the structure by reference to some other code. By contrast, if a routine exposes a class reference to outside code, there's no telling what that code may do with it.
Incidentally, the Holder class is also useful in a number of other scenarios. For example, if one has a Dictionary<String, Holder<Integer>> myDict, one may use Threading.Interlocked.Increment(myDict(myKey).Value)) to perform a thread-safe increment of the indicated item, much more efficiently than would be possible with a Dictionary<String, Integer>.

What I think you're asking is if Form2 can store a reference to the order structure that was passed in the constructor. The answer is no. If you want to store references, use a reference type (a class).

Related

Accessing an array without static references in another class (OOP)

I'm new to object-oriented-programming, and I have set a strict goal for myself for my current project which is not using static variables. In the process I will try to learn about OOP.
I'm using the Haxe language and it's one of the best languages I've ever seen.
I know a bit about C pointers, and that pointers only store the address of a variable so its pretty much the same variable, just taking up less space (especially for large variables).
Now back to the present, I want to have pointer references to an array of objects of one class because
I want these objects to interact with each other,
and I don't want to have any static references,
and I don't want to have every object holding a copy of that array.
How should I go along accessing this array?
Or is there another OOP design pattern or something?
Please correct me if I got something wrong.
There are many questions in this brief.
You can just pass along a context along all your variables, it will be passed by pointer
class Context{
var level:Level=null;
var enemies:Array<Enemy>=[];
}
class Enemy{
var ctx:Context;
function new(ctx){ this.ctx=ctx; }
}
class Main{
static function main(){
new Game(new Context());
}
}
and in game, pass along the context to everyone :
new Enemy(ctx);
etc...
Frankly it is often easier to use static for contexts, like
class Context{
static var level:Level;
}
But that's up to you :)
As a side note, all non primitives are pointers to structure (ex arrays) just like java.

How can I populate an instance of an object with random values?

Is there any way I can give AutoFixture an instance of an object and have it go through all the setters and set random data? The wiki examples only show how to obtain an instance from AutoFixture, e.g.
var autoGeneratedClass = fixture.Create<ComplexParent>();
My example use case is a factory method which generate instances of objects with dynamic properties based on a configuration. I want to test that my methods correctly, detect and interact (e.g. copy) these dynamic properties.
dynamic dynamicPropertyObject1 = factoryMethod(configuration);
dynamic dynamicPropertyObject2 = factoryMethod(configuration);
dynamicPropertyObject1.propA = random.Next();
dynamicPropertyObject1.CopyTo(dynamicPropertyObject2);
Assert.That(dynamicPropertyObject2.propA, Is.EqualTo(dynamicPropertyObject1.propA);
Thanks
AutoFixture has a lot of built-in heuristics for creating objects, including some for factory methods.
If AutoFixture finds no public constructors on a type, it starts to look for factory methods; i.e. static methods that return objects of the type of the class that defines that static method, e.g.
public class Foo
{
public static Foo CreateFoo();
// ... other members
}
If, on the other hand, a factory method exists on another class, you'll need to help AutoFixture a bit. The easiest way would be to use the Customize method:
fixture.Customize<Foo>(c => c
.FromFactory(() => FooFactory.CreateFoo())
.WithAutoProperties());
When you subsequently ask a Fixture object for a Foo object, FooFactory.CreateFoo() will be invoked, and because of WithAutoProperties that object will be populated with data created by AutoFixture.

In VB 2008, how can one subprocedure accept different arrays of a structure in different calls?

I'm writing a character creator for my friend's tabletop RPG using Visual Basic 2008 as a learning exercise so please be kind if I've made stupid choices. :]
I have three arrays of a structure, one called m_OwnedWeapons that's created from a structure called Weapons, one called m_OwnedArmor created from a structure called Armor, and one called m_OwnedPotions created from a structure called Potions. They have some similarities and several differences but a lot of the time I need to do an identical operation on each of them. For example, when the index in a listbox changes, my program searches through each of these arrays of a structure to find which holds the item and then it updates the displayed values (cost, description, etc).
My problem is that I'd like a way that I only have to write the search code one time. Right now I have to write it three times because it has to search each by name. I have this same code posted three times, only once it refers to m_OwnedPotions, once it refers to m_OwnedArmor, and once it refers to m_Owned Weapons:
LoopCountInteger = 0
If m_OwnedPotionsCounterInteger > 0 Then
Do Until LoopCountInteger >= m_OwnedPotionsCounterInteger Or ItemFoundBoolean = True
If InventoryListBox.SelectedItem.Equals(m_OwnedPotions(LoopCountInteger).NameString) Then
ItemFoundBoolean = True
End If
LoopCountInteger += 1
Loop
End If
Is there a way to maybe write some kind of subprocedure with this code that accepts the array of a structure name as its parameter? Is this not possible because one is an array of a structure of Weapons, one of Armor, and one of Items?
Maybe I just need one array of a structure called Items that will hold the fields required by all item types, but if I do it that way it seemed untidy because that one structure had so many fields unused for most items. I don't know.
Thanks for any help and suggestions.
So solving this type of problem is normally done through inheritance. You have three different types of objects that share some basic properties but are also different things. To represent these objects in your code, create a base class that will hold their common properties (name, cost, description, etc.) and a subclass for each of the more concrete types.
Here is one sort of exammple:
Public Class Equipment
Public Name As String
Public Desc As String
Public Cost As Integer
Public Weight As Integer
End Class
Public Class Weapon
Inherits Equipment
Public MinimumDamage As Integer
Public MaximumDamage As Integer
Public Speed As Integer
End Class
Public Class Potion
Inherits Equipment
Public Effect As String
End Class
Public Class Armor
Inherits Equipment
Public SpeedPenalty As Integer
Public ArmorClass As Integer
End Class
Now, using polymorphism you can write procedures that can operate on any of these items by accepting a parameter of the base type. Your program can also have a container that holds all of the equipment so you only have to search one list to find the object that is selected.

CObject, CStringArray and error C2248

class MyClass : public CObject
{
public:
MyClass();
private:
CStringArray m_myArray;
};
causes error c2248
What's wrong with this ?
I think it's related to the fact that CStringArray and MyClass both derive from CObject.
Legacy class derived from CObject currently uses CustomArray it just seems wrong to me so I would like to replace it by CStringArray.
Microsoft compiler error C2248 means "Members of a derived class cannot access private members of a base class."
I can only assume you're trying to directly reference MyClass::m_myArray from somewhere in your code, without using a public accessor function.
Update
The real answer is that the problem is caused by the copy-constructor for MyClass, attempting to copy m_myArray, but it can't, because CObject derived classes aren't copyable by default. The solution would be to write a copy constructor yourself, and rather than attempt to copy the array, copy the contents one at a time, from the source array to the destination array. Either that or use std::vector (which you should be doing anyway, as MFC containers are horrible).
You are trying to access some private member of CObject. Since both your MyClass and CStringArray derive from CObject, without more context it is impossible to know the exact problem.
The only idea that comes to mind, basically because I've fallen in the trap many times, is that CObject's copy constructor is private, so if you are trying to copy either the CStringArray or your own class, explicit or implicitly, you'll get the error.
UPDATE:
I've just taken a look at CObject's declaration and the assignment operator, too, is private. Everything else is either public or protected.
Error C2248 says "Members of a derived class cannot access private members of a base class."
CStringArray class dosn't expose Copy constructor and assignment operator, look in code for such places and replace the code with elemenet by elemnet copy.

why would I want a method that needs an instance?

Why would I want a method that needs an instance? Why wouldn't I make all my methods static?
Why would you not want any state anywhere in your program?
Can you imagine if there were no String instances, and everything on String was static? How would you represent two distinct sequences of characters? Now apply the same logic to other code.
Fundamentally, OO languages are built around the idea of objects with state: one instance of Book isn't the same an another instance of Book - each Book instance encapsulates its name, author, publication date etc. How would you model that with only static methods, and no instances?
Of course you could make all your methods static and pass in a Book as the first parameter on each call that needed to use the state. Behind the scenes, something pretty much like that is already happening... except you've then lost polymorphism, so interfaces, abstract classes etc are useless. Not good.
Because objects are state and behavior together, encapsulated into a single component.
If you have individual instances, it means they can each have private data that varies from instance to instance.
Static data and methods are shared at the class level. Individual instances cannot have different static data.
Static methods can't directly access the member variables within an object - they can only access static variables.
If you had a car class and a static data member like an integer in it, you could only ever have one car because you cant make multiple instances of cars and get multiple instances of that variable - you'd only ever have the single static one.
Every car can't have the same license plate number, thus ever car needs its own license plate variable.
The methods in the class that work with that variable need to be non-static to work on it directly then.
Using the example of a "Car" class, you might have a method called "startCar()". Obviously, you want this method to interact only with a particular "instance" of a car and not be global to ALL your cars. Example in Java:
public class Car {
public void startCar() {
// code to start car
}
}
public class MyProgram {
public static void main(String[] Args) {
Car myFord = new Car();
Car myOpel = new Car();
myCar.startCar; // starts the Car "myCar" and leaves "myOpel" alone
}
}
It's also worth noting that Static Methods may not make use of Instance Variables of the class in which they are defined.

Resources