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.
Related
Say I have a class with a number of methods - some private, some public.
In one of the public methods, I create a list of objects. This is then used across a number of other methods, which have simply been abstracted out to make code simpler.
So I might have:
public class MyClass
{
public void CreateList()
{
List<MyClass> MyList = new List<MyClass>();
... populate list
DedupeList();
ValidateList();
}
void DedupeList()
{
// do something using MyList
}
void ValidateList()
{
// do something using MyList
}
}
I was wondering what the best approach would be in this instance.
Make the list created by CreateList() a class level variable;
Pass the list a parameter to each of the sub-methods.
Ok, so it depends on what you're trying to achieve and what your classes responsibility is.
If you class represents a real thing which represents part of your domain, and which has state, then your private methods act on that state and I would therefore choose the former.
So
public class Basket
{
private IList<string> Contents;
public Basket()
{
Contents = new Contents();
}
public void Add(string Item)
{
Contents.Add(Item);
}
public void Empty()
{
Contents.Clear();
}
}
This is a trite example, but all I could think of.
If however your class doesn't represent an object with state, such as the calculator below which takes some input, acts on it, and returns it without storing anything, then the latter is better.
That said, there are other considerations, such as keeping code clean and easy to read (should be very high on your priority list), limiting the number of parameters etc being passed (any more than three is often regarded as messy). Example below of when I would elect to pass parameters.
public class InvestmentCalculator
{
pubilc IEnumerable<Stock> CalculateInvestmentValue(IEnumerable<Stock> Stocks)
{
foreach (var stock in stocks)
{
var itemValue = GetSotckValueFromMarket(stock);
stock.UpdateValue(itemValue)
AddProjection(stock);
}
}
public decimal GetStockValueFromMarket(Stock stock)
{
//Do something
}
public decimal AddProjection(Stock stock)
{
//Do something
}
}
I hope that this helps
It depends on meaning of the list. You have to find some answers. Should it be a part of the class or just a temporary variable that should live just along the method call? Is it a part of behavior of the class? How about threading? Even you may rethink if DedupeList and ValidateList methods have to be part of this class or do they deserve a separate class?
I recommend you to read "Implementation Patterns" by Kent Beck and "Clean Code" by Robert C. Martin. There are dozens of very helpful tips for these kind of little but frequent cases.
Ok so lets say I have a structure A like that:
Struct A{
private String _SomeText;
private int _SomeValue;
public A(String someText, int SomeValue) { /*.. set the initial values..*/ }
public String SomeText{ get { return _SomeText; } }
public int SomeValue{ get { return _SomeValue; } }
}
Now what I want to be able to do is to return that Structure A as a result of a method in a Class ABC, like that:
Class ABC{
public A getStructA(){
//creation of Struct A
return a;
}
}
I don't want any programmer using my library (which will have Struct A and Class ABC and some more stuff) to ever be able to create an instance of Struct A.
I want the only way for it to be created is as a return from the getStructA() method. Then the values can be accessed through the appropriate getters.
So is there any way to set a restrictions like that? So a Structure can't be instantiated outside of a certain class? Using C#, .Net4.0.
Thanks for your help.
---EDIT:----
To add some details on why am I trying to achieve this:
My class ABC has some "status" a person can query. This status has 2 string values and then a long list of integers.
There never will be a need to create an object/instance of "Status" by the programmer, the status can only be returned by "getStatus()" function of the class.
I do not want to split these 3 fields to different methods, as to obtain them I am calling Windows API (p/invoke) which returns similar struct with all 3 fields.
If I was indeed going to split it to 3 methods and not use the struct, I would have to either cache results or call the method from Windows API every time one of these 3 methods is called...
So I can either make a public struct and programmers can instantiate it if they want, which will be useless for them as there will be no methods which can accept it as a parameter. Or I can construct the library in such a way that this struct (or change it to a class if it makes things easier) can be obtained only as a return from the method.
If the "restricted" type is a struct, then no, there is no way to do that. The struct must be at least as public as the factory method, and if the struct is public then it can be constructed with its default constructor. However, you can do this:
public struct A
{
private string s;
private int i;
internal bool valid;
internal A(string s, int i)
{
this.s = s;
this.i = i;
this.valid = true;
}
...
and now you can have your library code check the "valid" flag. Instances of A can only be made either (1) by a method internal to your library that can call the internal constructor, or (2) by the default constructor. You can tell them apart with the valid flag.
A number of people have suggested using an interface, but that's a bit pointless; the whole point of using a struct is to get value type semantics and then you go boxing it into an interface. You might as well make it a class in the first place. If it is going to be a class then it is certainly possible to make a factory method; just make all the ctors of the class internal.
And of course I hope it goes without saying that none of this gear should be used to implement code that is resistant to attack by a fully-trusted user. Remember, this system is in place to protect good users from bad code, not good code from bad users. There is nothing whatsoever that stops fully trusted user code from calling whatever private methods they want in your library via reflection, or for that matter, altering the bits inside a struct with unsafe code.
Create a public interface and make the class private to the class invoking it.
public ISpecialReturnType
{
String SomeText{ get; }
int SomeValue{ get; }
}
class ABC{
public ISpecialReturnType getStructA(){
A a = //Get a value for a;
return a;
}
private struct A : ISpecialReturnType
{
private String _SomeText;
private int _SomeValue;
public A(String someText, int SomeValue) { /*.. set the initial values..*/ }
public String SomeText{ get { return _SomeText; } }
public int SomeValue{ get { return _SomeValue; } }
}
}
What exactly are you concerned about? A structure is fundamentally a collection of fields stuck together with duct tape. Since struct assignment copies all of the fields from one struct instance to another, outside the control of the struct type in question, structs have a very limited ability to enforce any sort of invariants, especially in multi-threaded code (unless a struct is exactly 1, 2, or 4 bytes, code that wants to create an instance which contains a mix of data copied from two different instances may do so pretty easily, and there's no way the struct can prevent it).
If you want to ensure that your methods will not accept any instances of a type other than those which your type has produced internally, you should use a class that either has only internal or private constructors. If you do that, you can be certain that you're getting the instances that you yourself produced.
EDIT
Based upon the revisions, I don't think the requested type of restriction is necessary or particularly helpful. It sounds like what's fundamentally desired to stick a bunch of values together and store them into a stuck-together group of variables held by the caller. If you declare a struct as simply:
public struct QueryResult {
public ExecutionDuration as Timespan;
public CompletionTime as DateTime;
public ReturnedMessage as String;
}
then a declaration:
QueryResult foo;
will effectively create three variables, named foo.ExecutionDuration, foo.CompletionTime, and foo.ReturnedMessage. The statement:
foo = queryPerformer.performQuery(...);
will set the values of those three variables according to the results of the function--essentially equivalent to:
{
var temp = queryPerformer.performQuery(...);
foo.ExecutionDuration = temp.ExecutionDuration
foo.CompletionTime = temp.CompletionTime;
foo.ReturnedMessage = temp.ReturnedMessage;
}
Nothing will prevent user code from doing whatever it wants with those three variables, but so what? If user code decides for whatever reason to say foo.ReturnedMessage = "George"; then foo.ReturnedMessage will equal George. The situation is really no different from if code had said:
int functionResult = doSomething();
and then later said functionResult = 43;. The behavior of functionResult, like any other variable, is to hold the last thing written to it. If the last thing written to it is the result of the last call to doSomething(), that's what it will hold. If the last thing written was something else, it will hold something else.
Note that a struct field, unlike a class field or a struct property, can only be changed either by writing to it, or by using a struct assignment statement to write all of the fields in one struct instance with the values in corresponding fields of another. From the consumer's perspective, a read-only struct property carries no such guarantee. A struct may happen to implement a property to behave that way, but without inspecting the code of the property there's no way to know whether the value it returns might be affected by some mutable object.
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
{
}
}
I have a class that looks like this:
public class MyModel{
public int TheId { get; set; }
public int ....
public string ....
}
I have another class that take a list of several types, including MyModel, and serializes the lists in json. It has several methods, one for each type of list.
public class ToJson{
public string MyModelToJson (List<MyModel> TheListOfMyModel) {
string ListOfMyModelInJson = "";
JavascriptSerializer TheSerializer = new ....
TheSerializer.RegisterConverters(....
ListOfMyModelInJson = TheSerializer.Serialize(TheListOfMyModel);
return ListOfMyModelInJson;
}
public string MyOtherModelToJson (List<MyOtherModel> TheListOfOtherModel) {....}
public string YetAnotherModelToJson (List<YetAnotherModelToJson> TheListOfYetAnotherModelToJson) {....}
}
What I want to do is encapsulate the serializing into MyModel, something like this:
public class MyModel{
public int TheId { get; set; }
public int ....
public string ....
public string MyModelToJson()
}
How can I encapsulate a method into an object so that it's available for a list of objects?
I thought of doing a foreach loop but that gets messy because in the calling method, you have to manipulate the json strings of each object in the list and concatenate them.
Let me know of OO principles of encapsulation apply in this case.
Thanks for your suggestions.
One way would be to define your ToJson as accepting a generic type:
public class ToJson<T>{
public string MyModelToJson (List<T> TheListOfMyModel) {
string ListOfMyModelInJson = "";
JavascriptSerializer TheSerializer = new ....
TheSerializer.RegisterConverters(....
ListOfMyModelInJson = TheSerializer.Serialize(TheListOfMyModel);
return ListOfMyModelInJson;
}
}
extension methods!
public static class JsonExtensions
{
public static string ToJson<T>(this List<T> list)
{
}
}
I'm not sure that I understand your question, but I think that what you want to do is not return a String but a JsonObject, JsonArray, or JsonPrimitive:
public class MyModel {
public JsonObject myModelToJson() ... //this method implements the interface!
}
Where JsonObject is a class that represents a json object.
Make this class implement an interface where the contract is that the return value is a JsonValue.
Then, in the ToJson class, return a JsonArray:
public class ToJson
public JsonArray myModelToJson(List<things that can be json-ized> myList) ...
}
Don't serialize the objects/arrays/primitives to a String until you absolutely need to, and let a library take care of the actual serialization.
That was a confusing answer.
Here's what I think you should do:
get hold of a decent json library. Ideally, it should have JsonObjects, JsonArrays, and JsonPrimitives which are subclasses of JsonElement. I've used Google gson in java, but I don't know what an equivalent C# version would be.
create an interface, JsonAble with one method -- toJson -- that returns a JsonElement.
implement this interface for all concerned classes
serializing a list of JsonAble objects is then very easy -- it becomes a JsonArray.
a decent json library should have a serialize method -- so you'll never have to worry about throwing strings around yourself
For what it's worth, I wouldn't remove the class at all. What you're talking about doing is adding an additional responsibility to your model, and apparently going against SRP heuristic. That is, you have a class whose current responsibility is to model data, and you're going to make it responsible for modeling data and also converting its data to some form, using various service classes that it now needs to know about. If the model class encapsulates GUI concepts like raising events for GUI, then it has divergent reasons to change - if the scheme for notifying the GUI changes and if the scheme for converting to JSON changes.
If it were me, I'd have the models inherit from a base class or define an interface as mentioned by Matt Fenwick, and have your ToJson class take a batch of those as input, process them, and return the result.
I understand the desire to eliminate the extra class, and might advocate it if it were a simple conversion involving only data elements of the class, but as soon as you need a service class of some kind to do the operation, it seems a poor fit for the model object, as you now cannot model data without a JavascriptSerializer. That's awkward if you want to model data that you don't then serialize.
One final thing that I can think of is that you can build on a'b'c'd'e'f'g'h's suggestion and piggy back the method onto some existing service, thus eliminating the class. If you just have a generic method on that service that implements the serialization, you can eliminate the separate class, since you no longer need a separate method for each model object type.
I'm creating an application that basically downloads and uploads files from various types of locations. I asked some advice on here and I was told that I should take an Object Oriented Approach with something like this, but this is my first real usage of OOP so I'm having a hard time understanding how to carry out what I want. Here is what I have so far:
public class FileListClass
{
public string sourcetype;
public string source;
public string destination;
public string destinationtype;
public bool deleteSource;
}
How do I actually enter a file into here in my main method? When I create a new list based on this class, .Add on the list requires an item of 'FileListClass' type - how do I create this?
you can do some thing lik ethis
FileListClass oFileListClass = new FileListClass();
oFileListClass.sourcetype="";
oFileListClass.source="";
oFileListClass.destination="";
oFileListClass.destinationtype="";
oFileListClass.deleteSource=false;
this will create one object, and you can create as many as possible like this with diffrent values.
if you wana keep this in List then create list of type FileListClass like
List<FileListClass > oListFileListClass = new List<FileListClass >();
then add all of your objects in this like
oListFileListClass.Add(oFileListClass);
Short answer:
var yourList = new System.Collections.Generic.List<FileListClass>();
yourList.Add(new FileListClass
{
sourcetype = "...",
source = "...",
...
});
Longer answer:
The above should work, but do take note that your class is not particularly well-designed (IMHO). It's more of a simple data record/container than a class that's "true" to OO principles. This may be just fine, depending on your requirements.
It's uncommon to expose fields directly in C#. Usually, only properties are exposed: public string SourceType { get; set; }
sourcetype and destinationtype are slightly suspect -- this might be a case where subclassing (class inheritance) might be suitable later on. Even without that, and without me knowing what exactly you're going to store in those two fields, have you considered using enums for them instead of plain strings?
In C#, it's common practice to name public members with CamelCase capitalization.
First, it's a bettere approach to define Enums for your constant types, something like
public enum SourceTypes
{
Network = 0,
WAN =1,
}
ecc. ecc.
then modify your FileLystClass as follows
public class FileListClass
{
public SouceTypes sourceType;
...
public DestinationTypes destinationType;
...
}
then, to answer your question.
You have defined a a class(a type) called FileListClass.
To use it, just create as many instance you want, populating the fields of the objects accordingly to your sources
public void CreateFileListList()
{
for (int i = 0; i <100; i++)
{
FileListClass flo = new FileListClass
flo.sourceType = SourceTypes.WAN;
flo.deletesource = true;
[...]
myList.add(flo);
}
}
I would suggest laying out the basic actions that are needed in your program:
DownloadFrom(String loc);
UploadFrom(String loc);
Then you can build lower levels of your app:
DownloadFrom(String loc);
HTTPConnect();
FTPConnect();
etc..
UploadFrom(String loc);
HTTPConnect();
FTPConnect();
etc..
At this point you can already have a feeling of the structure of your program, you can in fact create classes around your different actions:
class Connect {
HTTPConnect();
FTPConnect();
}
class Download : Connect{
DownloadFrom(String loc);
}
class Upload : Connect{
UploadFrom(String loc);
}
As you can see this is a first approach to OOP. There are many advantages to use a structure of Objects around your program but It would be too hard of an explanation. Try reading Google about it: Advantages of OOP.