I'm (as new oop and c# hobbiist) would like to ask for some guidance on the following (simplified) problem:
I've made a small class (lets call it A), with 4 properties, and few methods. Also a larger class (B) with ~10props, and it should contain 12 objects of class A, and a fair amount of functions to play with the props. I have my main class M (which is a windows form), a Filereader class (F) to handle all I/O.
I made a windows event on wm_devicechange, that the usb should be read, making an object of F. Now as F reads the file, it should fill the properties of the object from class B, which was created in the class F. Now the problem is, I cannot access this object of B from my main class. The question is how to do this right?
Should I make a property of F which is type B? Is that common practice?
Should I make the object of B in my main class?
When making a poperty in F of type B, does it only store and pass the reference if get from M?
I would like to try to avoid useless copiing of the object and such, but this topic of oop is so overwhelming for me right now, even after a few books, I am not even sure this question makes a lot of sense. I have read this article 3 times, but I am still confused what is good practice of handling such a "problem"?
Thanks
public class Form
{
USBReader reader;
CollectedData data;
public Form()
{
reader = new USBReader();
}
public void ReadUSBData()
{
data = reader.ReadUSBData();
}
}
// Type F
public class USBReader
{
public CollectedData ReadUSBData()
{ // usb read logic.
}
}
//Type B
public class CollectedData {
List<A> list = new List<A>();
}
public class A { }
A simple implementation can be like this where your USB reader returns data.
Generally the actions like reading data are methods on your objects with a return type of your data-model( here B and A). While the properties are attributes of your object. e.g. USBReader can have a property with self explanatory name like int BufferSize;
All approaches you mentioned are plausible, but one of them will probably be more intuitive and elegant.
What exactly is the B class? If it's some kind of result from reading the file, you'll probably want to return it from some method of F that does the reading.
If you assign object, it is just reference, so the same instance. If you need to share object between two objects, pass the object as parameter in constructor or some method/property. Then all objects with this reference has access to the same instance (data). If you need different "data set" - instance, simply create other instance of object...
You won't be wasting space by object assignments, since all objectsclasses in C# are reference types. However in my opinion you should decide between inheritance and nested classes
For inheritance, you will do something like:
public class F : B
{
//class F definition here
}
For nested class, you will have:
public class F
{
public class B
{
}
}
Related
Say I have a custom data class. It just holds data in a meaningful way.
The class might look like:
class MyClass
{
public struct MyType
{
public string parameter;
public string data;
public string value;
}
public List<MyType> myTypeList= new List<MyType>();
}
Say I have a program that creates many of these classes. The data is filled from parsing a number of files and the List<MyType> will have an indefinite number of items when done grabbing data. I then use this data in several ways throughout the program (Create documents, display on GUI, etc...).
When I add to the list in my Parsing class, I must first create a new object of MyType and then add it to myTypeList. So the parsing class has to actually know of and use the inner object type. Once it is added, though, I can just use an instance of MyClass to access the fields directly without any knowledge of type.
Such as:
string myString = myClassInstance.myTypeList[0].parameter;
Is it better to create a method inside the MyClass that lets the parsing class pass in data without knowledge of the underlying type? If so, what is the best way of doing this?
I can think of several ways to do it, I just don't know if it's the best or correct way. I guess it would better generalize the code, but could be less readable when adding data.
Edit: Adding in usage differences due to comment.
class MyParser
{
public List<MyClass> ParseFile(string[] lines)
{
List<MyClass> myClassInstance = new MyClass();
foreach(string line in lines)
{
MyType typeInstance = new MyType();
typeInstance.parameter = line.Substring(0, 1);
typeInstance.data = line.Substring(1, 1);
typeInstance.value = line.Substring(2, 1);
myClassInstance.myTypeList.Add(typeInstance);
}
}
}
Vs. Something like:
class MyParser
{
public List<MyClass> ParseFile(string[] lines)
{
List<MyClass> myClassInstance = new MyClass();
foreach(string line in lines)
{
myClassInstance.AddData(line.Substring(0, 1),
line.Substring(1, 1),
line.Substring(2, 1));
}
}
}
No, it's best to keep the MyType class separate. It has one purpose, to represent whatever it represents. If it does that then it's perfect and doesn't need to change. (Look at the Single Responsibility Principle.)
In most cases it makes sense to do exactly what you're doing. Another class has its own responsibility, to take some input - a file, the results of a SQL query, etc., and read it into a class or collection of classes.
Sometimes if it gets complicated it's good to break it down even further - perhaps one class reads from a file and other converts a record from the file into a class. But that's often overkill. At most it's usually enough to break those up into separate methods in one class.
The only case I can think of where a class "owns" the function of parsing something is with value types like int or DateTime or classes like IpAddress where string representations are so common that it makes sense to have methods like int.Parse(string) or DateTime.Parse(string). But that wouldn't make sense for something more complex like parsing a record from a file or a SQL record.
Can someone please explain what is the difference between
ParentClass obj= new ChildChildClass();
and
ParentClass obj= new ParentClass();
Since both
class ParentClass{
public void ParentClassMethod(){
}
}
class ChildClass : ParentClass{
public void ChildClassMethod(){
}
}
As per my understanding what is accessible remains same in both cases. So what is the point?
You're instantiating two entirely different objects (that both happen to be, at some level, a ParentClass). Though the code will now see them as the same type, the underlying object will be different.
I could take the same idea and make it more obvious:
object o = "Hello World!";
object o2 = 15;
string and int are both objects, so this is fine. However the underlying type is certainly different here.
You can override virtual methods. A simple example:
void Main()
{
A realA = new A();
A actuallyB = new B();
Console.WriteLine(realA.GetName()); // John
Console.WriteLine(actuallyB.GetName()); // Gillian
PrintName(realA); // John
PrintName(actuallyB); // Gillian
}
public void PrintName(A anyA)
{
Console.WriteLine(anyA.GetName());
}
public class A
{
public virtual string GetName()
{
return "John";
}
}
public class B : A
{
public override string GetName()
{
return "Gillian";
}
}
Your two classes can have different behaviour (within the bounds of Liskov Substitution Principle, of course), but the helper method PrintName will work with both.
In fact, this is the whole reason for the existence of inheritance - you expose some useful interface, and everyone who's using it can treat it one way. If you want a more real world example, let's look at the Stream class. For example, you might have a helper method that reads an image from a stream. Now, when you need to read an image from a file, you just pass a file stream to your helper method. When you want to read an image from a database, you just pass a database stream. When you want to read an image from a web server... As long as the streams conform to the stream interface (and the truth is, streams aren't exactly perfectly designed ;)), you can switch them at will, and everything will work as expected.
It is quite difficult to say like "The difference is in..."
It is one of the OOP principles called Inheritance. It means that ChildClass at the same time is ParentClass. So you can store both this types in collection of type ParentType or to pass as a parameter. But to access child's method you need to cast to child's type.
ParentClass obj = new ChildChildClass();
Here obj is actually a ChildChildClass and at any time you can cast it back to ParentClass and call the methods available in ParentClass.
The advantage for such usages is you can have some common functionality which works with ParentClass only and there you want to pass ChildChildClass also as it is also a ParentClass.
This is a 2 part question.
Firstly
I have a class called ComponentList that looks like this:
public class ComponentList<T> : List<T> where T : Component
{
}
Now I want to create an empty list of typeless ComponentLists:
List<ComponentList<>> MasterList = new List<ComponentList<>>();
I get an error because the ComponentList wants a generic type specified even though I'm not trying to initialize any ComponentLists yet (just the MasterList that contains them). How would I declare the MasterList of ComponentLists without initializing any ComponentLists (as I plan to initialize them during runtime with types only known at runtime)? After all, the MasterList needs to contain ComponentLists of different generic types, not just one.
Secondly
I know this one has been asked before, but I can't seem to wrap my head around the concepts of any of the proposed solutions.
As you know, I have a List<> called MasterList which is a list of ComponentLists (a custom class). A ComponentList is a generic class of an undefined type (that is constrained to being a subtype of Component).
In the following example, I'm trying to check if a ComponentList generic type (referenced from MasterList) is the same as this class (the class the code's being called from).
if (MasterList[i].GetType() == typeof(ComponentList<this.GetType()>))
{
}
Problem is, the code is meant to be automatically called from unknown child classes, not from this parent class. So the ComponentList generic type needs to be compared with the type of the child class, not this base class. Hence the "this.GetType" inplace of what would be the hardcoded name of the actual base class.
The this.GetType() type passed in the ComponentList<> returns a "type expected" error apparently because GetType() returns compile time type, not runtime type (which is what I need).
So how could I get the runtime type? And if I can't, what would be the best alternative to accomplishing what I'm trying to do? (I've heard a bit about something called reflections that might help me but I really don't understand).
You cannot determine generic types at runtime. C# (all .Net, actually) is designed that way on purpose. The compiler treats a generic type virtually same way as an explicitly defined type.
Consider the following:
class MyGenericClass<T>
{
public static T MyProperty { get; set; }
}
class MyIntClass
{
public static int MyProperty { get; set; }
}
class UseThem
{
public void test()
{
// both are JIT'ed to be exactly the same machine code
var foo = MyGenericClass<int>.MyProperty;
var bar = MyOtherClass.MyProperty;
}
}
Thus, you must provide a type for the generic class so that JIT knows what to compile.
Possible Alternative
If all of the possible types which could possible end up being the generic type are similar (inherit from the same base class or implement a similar interface), then you can instantiate the generic class with an interface or base class as the generic type:
List<ComponentList<ComponentBase>> MasterList = new List<ComponentList<ComponentBase>>();
// -OR-
List<ComponentList<IMyComponent>> MasterList = new List<ComponentList<IMyComponent>>();
I have a hunch that you should be able to define a common interface or base class with a little creative refactoring. :)
I've run into this issue as well when I was trying to set up an entity-component system for a game written in C#. There's really isn't a way to store components as their actual types, you have to store them all as Components and cast them.
The way I have it set up is as a Dictionary<Type, List<Component>> as a private member of a ComponentManager class. The method that adds components is generic and checks if it's Type is contained in the Dictionary, so getting an IEnumerable<SpecificComponent> is as simple as:
public IEnumerable<T> EnumerateComponents<T>()
where T : Component
{
foreach (Component c in components[typeof(T)])
yield return (T)c;
}
(You'll also want to check that the dictionary contains typeof(T), that bit is built-in with a custom collection of mine that inherits from Dictionary to avoid exceptions in cases like this.)
Type safety is "guaranteed" as long as the dictionary is never modified outside of a generic method (and definitely not directly accessible from the outside). Not ideal, but it's fast enough where it will never be your bottleneck.
EDIT
Something to explore might be C# 4's dynamic keyword. I haven't looked into it much, but storing the components as a List<dynamic> might work better (or it may introduce way too much overhead), just something to think about.
I don't think what you are asking is possible, however maybe this is what you need.
public class ComponentA : Component { }
public class ComponentB : Component { }
public class Component { }
public class ComponentList<T> : List<T> where T : Component
{
}
class Program
{
static void Main(string[] args)
{
ComponentList<Component> MasterList = new ComponentList<Component>();
MasterList.Add(new ComponentA());
MasterList.Add(new ComponentB());
for (int i = 0; i < MasterList.Count; i++)
{
if (MasterList[i] is ComponentA)
{
}
}
}
}
I have a data object which has a base class with three derived classes,
public enum ModelType
{
A,
B,
C
}
public abstract class Parent
{
protected ModelType type;
}
public class ChildA: Parent
{
private new ModelType type = ModelType.A;
}
public class ChildB: Parent
public class ChildC: Parent
The same type field is in the other 2 children with corresponding ModelTypes.
I have another layer between the forms that has some higher level additional information about the data object and an instance of Parent(). I am trying to simplify the problem a lot so I apologise if I am not being clear and have not given enough information.
public enum UIModelType
{
A,
B,
C,
None
}
public class DataObject
{
private Parent someData;
private UIModelType type;
}
The fields have getter and setter properties.
The UI only communicates with the DataObject class and cannot see the lower level someData object.
Now at some point during the UI (which is a wizard to fill in the information in the data objects), the user can select A, B or C. My problem is how to communicate this information without too much code repetition. Right now I have an enum between the UI and DataObject class. So if user selects A, it assigns a data type as A using the enum. The DataObject class now instantiates the someData object with ChildA(). The problem is to communicate between the DataObject and someData object I have another enum with A, B and C to communicate the type.
Would it be healthier to use typeof instead, although I have read that that is not the best way to go.
I need to do many equality checks with the data type (ABC) from the UI all the way to the lower level data object and hence I had thought enums is the fastest way but it doesn't feel right to have so many enums of the same type in different classes. Am I missing something very obvious here?
Rather than using typeof or enum, you could use is.
private Parent someData = new ChildA();
if (someData is Parent) { } // Returns true.
if (someData is ChildA) { } // Returns true.
if (someData is ChildB) { } // Returns false.
However, if I understand your question correctly, it sounds like you're doing these checks because you need to continually downcast the someData object to provide functionality for the DataObject class that depends on the type of someData. If this is the case, you might want to consider refactoring your code, as repeated downcasting can can make code difficult to read and defies some traditional concepts of object-oriented programming.
Edit:
Ok, I think I understand your question better, now. You're looking for a better way of creating children of the Parent object (i.e. using the factory pattern) than by using an enum.
You could create the instance dynamically based on the type name:
var typeName = GetTheTypeTheUserWants();
var type = System.Type.GetType(typeName, false, true);
if (type == null) throw new Exception();
var someData = Activator.CreateInstance(type) as Parent;
if (someData == null) throw new Exception();
Using an enum might be easier, but this method allows you to create new subclasses of Parent without updating your enum.
If I still missed the point of your question, sorry.
Just use 'typeof' and be done with it. It sounds like you are only using enums because of some tiny increase in performance that you might get. Just go with whatever produces the easiest to read / maintain code (typeof in this case).
I don't think that you have to worry about performance in your wizard because the slowest part is going to be the user selecting what type of object they want.
I would get rid of ModelType. You're just creating another way to represent information you already have, which will just be annoying to maintain.
In your DataObject class, your UIModelType could go away too. Wherever you thought you were going to use it could probably be replaced with:
if (this.someData is ChildA) {
} else if (this.someData is ChildB) {
} ...
I want to understand the difference between 3 sets of snippets below:
private static FirstObject o = new FirstObject();
public class ClassA
{
}
//-----------------------------------------------------
public class ClassA
{
private static FirstObject o = new FirstObject();
}
//-----------------------------------------------------
public class ClassA
{
private static FirstObject o;
public ClassA
{
o = new FirstObject();
}
}
Please help me understand in terms of scope, memory, performance and usage of these.
Thank you.
Invalid, as you can't have a variable outside of object
The proper way - the class has a static member, which is initialized when the class is accessed for the first time
Very bad, because every time when new object is created the static object will be recreated.
The first option will not compile. A static variable in C# must be scoped to a class or struct.
The second option is the preferred mechanism.
The third option is wrong because this creates a new FirstObject each time an instance of ClassA is created, which is almost certainly not what you want.
A fourth option would be to leverage a static constructor, e.g.,
public class ClassA
{
private static FirstObject o;
static ClassA
{
o = new FirstObject();
}
}
This option is useful if there is some special construction constraints for FirstObject. In this example, though, choose option 2 over option 4. Just know that option 4 exists.
Three cases below...
Assuming a typo here missing some outer construct... "o" is declared so that it will be globally accessible, as a single object, to the entire application. It will have one common set of all properties and data. It can be access directly by "Namespace.o"
"o" is declared so that it will be globally accessible, as a single object, to the entire application, However it is only accessible through another defined instance of "ClassA". Each separate instance of ClassA will have the same, single "o" object with the same properties and data.
This doesn't look right to me, I'm assuming "ol" is supposed to "o;". Even with this the code looks like its missing something. if the Line "o = new FirstObject" is correct it is not accessible in this fashion.