Suppose i am having a class
Class ABC
{
public string Method1()
{
return "a";
}
public string Method2()
{
return "b";
}
public string Method3()
{
return "c";
}
}
and Now i am calling this methods in two ways like :
ABC obj=new ABC();
Response.Write(obj.Method1());
Response.Write(obj.Method2());
Another way
Response.Write(new ABC().Method1());
Response.Write(new ABC().Method2());
The output will be same for above two method .
Can some please help me understanding the difference between obj.Method1() and new ABC().Method1()
Thanks in Advance..
obj and new ABC() are separate instances. In your example the output is the same because there is no instance-level data to show.
Try this to see the difference:
Class ABC
{
public string Name = "default";
public string Method1()
{
return "a";
}
}
then use the code below to show the difference with instance-level data:
ABC obj=new ABC();
obj.Name = "NewObject";
Response.Write(obj.Method1());
Response.Write(obj.Name);
Response.Write(new ABC().Method1());
Response.Write(new ABC().Name);
What #d-stanley is trying to say is that you allocate memory on creation that is is very valuable resource.
And the more complete answer is this: Classes created with some logic in mind. Although is perfectly workable Response.Write(new ABC().Method1()); but this is very short function and not as much useless... When you design class you implemented some logic boundary functionality and properties. For example FileStream has a inner property of Stream and make it accessible via various properties and you could set it in overloaded Open() method and destroy it in Dispose() method. And for example another class BinaryReader implements Stream also but threat it differently. From your logic you could implement all functions on single class - some MotherOfAllFunctions class the implements all the functions of FileStream and BinaryReader - but it's not a way of doing it.
Another point: In most of the cases some (or huge) ammount of memory is taken to initialize some internal logic of the class - for example SqlConnection class. Then you call Open() or any other method to call a database - there's some very powerful mechanics is thrown kick-in to support state machine initialization, managed-to-unmanagment calls and a lot of code could be executed.
Actually what you doing in any new SomeCLass().SomeMethod<int>(ref AnotherObject) is:
Response.Write(
var tmpABC = new ABC(); // Constructor call . Executed always (may throw)
string result = tmpABC.Method1(); // Or whatever could be casted to `string`
tmpABC.Dispose(); // GC will kick-in and try to free memory
return result;
);
As you see - this is the same code as if you have written it in this way. So what happens here is a lot of memory allocations and almost immediately all this valuable memory is thrown away. It makes more sense to initialize ABC() class and all it functionality power once and then use it everywhere so minimize memory over allocation. For example - it doesn't make any sense to open SqlConnection function in every function call in your DAL class the then immediately close it - better declare local variable and keep it alive - some fully initialized classes live as long as application thread process exist. So in case of this code style:
public class Program
{
private static FileStream streamToLogFile = new FileStream(...);
public int Main(string [] args)
{
new Run(new Form1(streamToLogFile));
}
}
In this logic - there's no need to keep class Form1 and I created it inline but all the functions the need to access FileStream object (valuable resource !) will access the same instance that been initialized only once.
Related
I'm into learning SOLID principles - especially Inversion Of Control-DI-Decoupling, and as I'm reviewing one of my codes, I noticed that this one method (see below) gets my attention.
This code will be called by any methods that needs to read the json file, accepts string values that will be used to lookup on a json file. But as you can see(I simplified the code - excluded the exception handling for the sake of this topic), I'm not sure where to start(there are a lot of initializations or dependencies?? happening and I'm not sure where to start).
Could this method/scenario a good candidate to start with? Which do you think should I retain? and needs to be decoupled?
Thanks.
public async Task<object> ReadJsonByKey(string jsonPath, string jsonKey)
{
// First - is it okay to have an initialization at this stage?
var value = new object();
// Second - is this fine to have this in the scope of this method?
using (TextReader reader = File.OpenText(jsonPath))
{
// Third - Calling Jobject that accepts new instance of JsonTextReader
var jObject = await JObject.LoadAsync(new JsonTextReader(reader));
obj = jObject.SelectToken(jsonKey);
}
return value;
}
The reason also I asked this is because (based from the standards ) loosely-coupled stuff can be easily tested - i.e, Unit Testing
[UnitTestSuite]
[TestCase1]
// Method should only be able to accept ".json" or ".txt" file
[TestCase2]
// JsonPath file is valid file system
[TestCase3]
// Method should be able to retrieve a node value based from a specific json and key
[TestCase4]
// Json-text file is not empty
It looks like you're trying to decouple an infrastructural concern from your application code.
Assuming that's the case you need a class which is responsible for reading the data:
public interface IDataReader
{
Task<object> ReadJsonByKey(string jsonPath, string jsonKey)
}
The implementation of which would be your above code:
public class DataReader : IDataReader
{
public async Task<object> ReadJsonByKey(string jsonPath, string jsonKey)
{
// First - is it okay to have an initialization at this stage?
var value = new object();
// Second - is this fine to have this in the scope of this method?
using (TextReader reader = File.OpenText(jsonPath))
{
// Third - Calling Jobject that accepts new instance of JsonTextReader
var jObject = await JObject.LoadAsync(new JsonTextReader(reader));
obj = jObject.SelectToken(jsonKey);
}
return value;
}
}
However this class is now doing both file reading & de-serialization so you could further separate into:
public class DataReader : IDataReader
{
IDeserializer _deserializer;
public DataReader(IDeserializer deserializer)
{
_deserializer = deserializer;
}
public async Task<object> ReadJsonByKey(string jsonPath, string jsonKey)
{
var json = File.ReadAllText(jsonPath);
return _deserializer.Deserialize(json, jsonKey);
}
}
This would mean that could now unit test your IDeserializer independently of the file system dependency.
However, the main benefit should be that you can now mock the IDataReader implementation when unit testing your application code.
Make the function like:
public async Task<object> ReadJsonByKey(TextReader reader, string jsonKey)
Now the function works with any TextReader implementation, so you can pass a TextReader that reads from file or from memory or from any other data source.
The only thing that prevents you from unit-testing this properly is the File reference, which is a static. You won't be able to provide the method with a file, because it would have to physically exist. There are two ways you can go about solving this.
First, if it's possible, you could pass something else rather than a path to the method - a FileStream for example.
Second, arguably better, you would abstract the file system (I recommend using the System.IO.Abstractions and then the related TestingHelpers package) into a private field, pass the dependency via ctor injection.
private readonly IFileSystem fileSystem;
public MyClass(IFileSystem fileSystem)
{
this.fileSystem = fileSystem;
}
And then in your method you'd use
fileSystem.File.OpenText(jsonPath);
This should allow you to unit-test this method with ease, by passing a MockFileSystem and creating a json file in-memory for the method to read. And unit-testability is actually a good indicator that your method is maintainable and has a well defined purpose - if you can test it easily with a not-so-complicated unit test, then it's probably good. If you can't, then it's definitely bad.
So I have a number of different potential object that can output data (strings). What I want to be able to do, is to Run a generic Output.WriteLine function, with the potential arguments that define where you want it to be outputted to. What I've got for code -
//Defined in static class Const
public enum Out : int { Debug = 0x01, Main = 0x02, Code = 0x04 };
static class Output
{
private static List<object> RetrieveOutputMechanisms(Const.Out output)
{
List<object> result = new List<object>();
#if DEBUG
if (bitmask(output, Const.Out.Debug))
result.Add(1);//Console); //I want to add Console here, but its static
#endif
if (bitmask(output, Const.Out.Main))
if (Program.mainForm != null)
result.Add(Program.mainForm.Box);
if (bitmask(output, Const.Out.Code))
if (Program.code!= null)
result.Add(Program.code.Box);
return result;
}
public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
Console.WriteLine(
List<object> writers = RetrieveOutputMechanisms(output);
foreach (object writer in writers)
writer.WriteLine(str, color);
}
}
The point of this, is that the output destinations are not always existent, as they are on forms that may or may not exist when these calls are called. So the idea is to determine which ones you're trying to print to, determine if it exists, add it to the list of things to be printed to, then loop through and print to all of them if they implement the "WriteLine" method.
The two problems that I've come across, are
That Console is a static class, and can't properly (as far as my knowledge goes) be added to the object list.
I don't know how I can assert that the objects in the list define WriteLine, and cast them to something that would apply to more than one base Type. Assuming I can get Console to work properly in this scheme, that would be the obvious problem, its not of the same base type as the actual Boxes, but also, if I had something that wasnt a Box, then it would be lovely to do something like
foreach (object writer in writers)
.WriteLine(str, color)
so that I wouldn't have to individually cast them.
The bigger reason that I don't simply WriteLine from the RetrieveOutputMechanisms function, is that I want this to cover more than just WriteLine, which means that I would need to copy the bitmask code to each function.
EDIT: I realise that adding public properties to Program is a bad idea, if you know how I can avoid it (the necessity coming from needing to be able to access any WriteLine-able form objects that come and go, from anywhere), by all means please elaborate.
One way would be to use an Action (a delegate) and store those in your List. This will work for Console and any other class as you can easily write a lambda (or a 2.0 delegate) to map your output variables to the right parameters in the called method. There will be no need for casting. It could work something like this:
(This assumes you are using C# 3.5 or later but you can do all this in anything from 2.0 and on using delegates)
static class Output
{
private static List<Action<string, Color>> RetrieveOutputMechanisms(Const.Out output)
{
List<Action<string, Color>> result = new List<string, Color>();
#if DEBUG
if (bitmask(output, Const.Out.Debug))
result.Add((s, c) => Console.WriteLine(s, c)); //I want to add Console here, but its static
#endif
if (bitmask(output, Const.Out.Main))
if (Program.mainForm != null)
result.Add((s, c) => Program.mainForm.Box.WriteLine(s, c));
if (bitmask(output, Const.Out.Code))
if (Program.code!= null)
result.Add((s, c) => Program.code.Box.WriteLine(s, c));
return result;
}
public static void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
var writers = RetrieveOutputMechanisms(output);
foreach (var writer in writers)
writer(str, color);
}
}
(edit to add)
You could change this more significantly to allow classes to "register" to be able to do the writing for a specific "output mechanism" in the Output class itself. You could make Output a singleton (there are arguments against doing that but it would be better than sticking public static variables in your main program for this purpose). Here is an example with more significant changes to your original class:
public sealed class Output
{
private Dictionary<Out, Action<string, Color>> registeredWriters = new Dictionary<Out, Action<string, Color>>();
public static readonly Output Instance = new Output();
private void Output() { } // Empty private constructor so another instance cannot be created.
public void Unregister(Out outType)
{
if (registeredWriters.ContainsKey(outType))
registeredWriters.Remove(outType);
}
// Assumes caller will not combine the flags for outType here
public void Register(Out outType, Action<string, Color> writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (registeredWriters.ContainsKey(outType))
{
// You could throw an exception, such as InvalidOperationException if you don't want to
// allow a different writer assigned once one has already been.
registeredWriters[outType] = writer;
}
else
{
registeredWriters.Add(outType, writer);
}
}
public void WriteLine(Color color, string str, Const.Out output = Const.Out.Debug & Const.Out.Main)
{
bool includeDebug = false;
#if DEBUG
includeDebug = true;
#endif
foreach (var outType in registeredWriters.Keys)
{
if (outType == Const.Out.Debug && !includeDebug)
continue;
if (bitmask(output, outType))
registeredWriters[outType](str, color);
}
}
}
Then elsewhere in your program, such as in the form class, to register a writer, do:
Output.Instance.Register(Const.Out.Main, (s, c) => this.Box.WriteLine(s, c));
When your form is unloaded you can then do:
Output.Instance.Unregister(Const.Out.Main);
Then another way would be to not use a singleton. You could then have more than one Output instance for different purposes and then inject these into your other classes. For instance, change the constructor for your main form to accept an Output parameter and store this is an object variable for later use. The main form could then pass this on to a child form that also needs it.
If your objects that have data that need to be written behave like this:
A always writes to console and log
B always writes to log
C always writes to console
For all data, then your best bet would be to declare an interface and have each of them implement the interface method for output. Then, in your calling code, declare them not as their actual types but instead of type IOutput or whatever interface u call that has the method. Then have two helper methods, one for actually outputting to console and one for actually outputting to a log file. A would call both helpers, B and C their respective ones.
If, on the other hand, your objects will write to various logs at differing times:
A, B and C sometimes write to console and sometimes to log, depending on some property
Then I would recommend you create an event handler for when a class wants something to be written. Then, have the logic that discerns what writes to console and what writes to log in a listener class and attach the appropriate ones to that output event. That way, you can keep the logic about what is being written to where in classes that encapsulate just that functionality, while leaving the A, B and C classes free of dependencies that may come to bite you down the road. Consider having a monolithic method as you describe which uses a bitmask. As soon as the behavior of A, B or C's logging changes, or if you need to add a new output, you suddenly need to worry about one class or method affecting all of them at once. This makes it less maintainable, and also trickier to test for bugs.
MethodInfo methodname = typeof(object).GetMethod("MethodA");
Then just use a if statement to check if methodname is null or not.
I'm trying to use this great project but since i need to scan many images the process takes a lot of time so i was thinking about multi-threading it.
However, since the class that makes the actual processing of the images uses Static methods and is manipulating Objects by ref i'm not really sure how to do it right. the method that I call from my main Thread is:
public static void ScanPage(ref System.Collections.ArrayList CodesRead, Bitmap bmp, int numscans, ScanDirection direction, BarcodeType types)
{
//added only the signature, actual class has over 1000 rows
//inside this function there are calls to other
//static functions that makes some image processing
}
My question is if it's safe to use use this function like this:
List<string> filePaths = new List<string>();
Parallel.For(0, filePaths.Count, a =>
{
ArrayList al = new ArrayList();
BarcodeImaging.ScanPage(ref al, ...);
});
I've spent hours debugging it and most of the time the results i got were correct but i did encounter several errors which i now can't seem to reproduce.
EDIT
I pasted the code of the class to here: http://pastebin.com/UeE6qBHx
I'm pretty sure it is thread safe.
There are two fields, which are configuration fields and are not modified inside the class.
So basically this class has no state and all calculation has no side effects
(Unless I don't see something very obscure).
Ref modifier is not needed here, because the reference is not modified.
There's no way of telling unless you know if it stores values in local variables or in a field (in the static class, not the method).
All local variables will be fine and instanced per call, but the fields will not.
A very bad example:
public static class TestClass
{
public static double Data;
public static string StringData = "";
// Can, and will quite often, return wrong values.
// for example returning the result of f(8) instead of f(5)
// if Data is changed before StringData is calculated.
public static string ChangeStaticVariables(int x)
{
Data = Math.Sqrt(x) + Math.Sqrt(x);
StringData = Data.ToString("0.000");
return StringData;
}
// Won't return the wrong values, as the variables
// can't be changed by other threads.
public static string NonStaticVariables(int x)
{
var tData = Math.Sqrt(x) + Math.Sqrt(x);
return Data.ToString("0.000");
}
}
Long story short
Say I have the following code:
// a class like this
class FirstObject {
public Object OneProperty {
get;
set;
}
// (other properties)
public Object OneMethod() {
// logic
}
}
// and another class with properties and methods names
// which are similar or exact the same if needed
class SecondObject {
public Object OneProperty {
get;
set;
}
// (other properties)
public Object OneMethod(String canHaveParameters) {
// logic
}
}
// the consuming code would be something like this
public static void main(String[] args) {
FirstObject myObject=new FirstObject();
// Use its properties and methods
Console.WriteLine("FirstObject.OneProperty value: "+myObject.OneProperty);
Console.WriteLine("FirstObject.OneMethod returned value: "+myObject.OneMethod());
// Now, for some reason, continue to use the
// same object but with another type
// -----> CHANGE FirstObject to SecondObject HERE <-----
// Continue to use properties and methods but
// this time calls were being made to SecondObject properties and Methods
Console.WriteLine("SecondObject.OneProperty value: "+myObject.OneProperty);
Console.WriteLine("SecondObject.OneMethod returned value: "+myObject.OneMethod(oneParameter));
}
Is it possible to change FirstObject type to SecondObject and continue to use it's properties and methods?
I've total control over FirstObject, but SecondObject is sealed and totally out of my scope!
May I achieve this through reflection? How? What do you think of the work that it might take to do it? Obviously both class can be a LOT more complex than the example above.
Both class can have templates like FirstObject<T> and SecondObject<T> which is intimidating me to use reflection for such a task!
Problem in reality
I've tried to state my problem the easier way for the sake of simplicity and to try to extract some knowledge to solve it but, by looking to the answers, it seems obvious to me that, to help me, you need to understand my real problem because changing object type is only the tip of the iceberg.
I'm developing a Workflow Definition API. The main objective is to have a API able to be reusable on top of any engine I might want to use(CLR through WF4, NetBPM, etc.).
By now I'm writing the middle layer to translate that API to WF4 to run workflows through the CLR.
What I've already accomplished
The API concept, at this stage, is somehow similar to WF4 with ActivityStates with In/Out Arguments and Data(Variables) running through the ActivityStates using their arguments.
Very simplified API in pseudo-code:
class Argument {
object Value;
}
class Data {
String Name;
Type ValueType;
object Value;
}
class ActivityState {
String DescriptiveName;
}
class MyIf: ActivityState {
InArgument Condition;
ActivityState Then;
ActivityState Else;
}
class MySequence: ActivityState {
Collection<Data> Data;
Collection<ActivityState> Activities;
}
My initial approach to translate this to WF4 was too run through the ActivitiesStates graph and do a somehow direct assignment of properties, using reflection where needed.
Again simplified pseudo-code, something like:
new Activities.If() {
DisplayName=myIf.DescriptiveName,
Condition=TranslateArgumentTo_WF4_Argument(myIf.Condition),
Then=TranslateActivityStateTo_WF4_Activity(myIf.Then),
Else=TranslateActivityStateTo_WF4_Activity(myIf.Else)
}
new Activities.Sequence() {
DisplayName=mySequence.DescriptiveName,
Variables=TranslateDataTo_WF4_Variables(mySequence.Variables),
Activities=TranslateActivitiesStatesTo_WF4_Activities(mySequence.Activities)
}
At the end of the translation I would have an executable System.Activities.Activity object. I've already accomplished this easily.
The big issue
A big issue with this approach appeared when I began the Data object to System.Activities.Variable translation. The problem is WF4 separates the workflow execution from the context. Because of that both Arguments and Variables are LocationReferences that must be accessed through var.Get(context) function for the engine to know where they are at runtime.
Something like this is easily accomplished using WF4:
Variable<string> var1=new Variable<string>("varname1", "string value");
Variable<int> var2=new Variable<int>("varname2", 123);
return new Sequence {
Name="Sequence Activity",
Variables=new Collection<Variable> { var1, var2 },
Activities=new Collection<Activity>(){
new Write() {
Name="WriteActivity1",
Text=new InArgument<string>(
context =>
String.Format("String value: {0}", var1.Get(context)))
},
new Write() {
//Name = "WriteActivity2",
Text=new InArgument<string>(
context =>
String.Format("Int value: {0}", var2.Get(context)))
}
}
};
but if I want to represent the same workflow through my API:
Data<string> var1=new Data<string>("varname1", "string value");
Data<int> var2=new Data<int>("varname2", 123);
return new Sequence() {
DescriptiveName="Sequence Activity",
Data=new Collection<Data> { var1, var2 },
Activities=new Collection<ActivityState>(){
new Write() {
DescriptiveName="WriteActivity1",
Text="String value: "+var1 // <-- BIG PROBLEM !!
},
new Write() {
DescriptiveName="WriteActivity2",
Text="Int value: "+Convert.ToInt32(var2) // ANOTHER BIG PROBLEM !!
}
}
};
I end up with a BIG PROBLEM when using Data objects as Variables. I really don't know how to allow the developer, using my API, to use Data objects wherever who wants(just like in WF4) and later translate that Data to System.Activities.Variable.
Solutions come to mind
If you now understand my problem, the FirstObject and SecondObject are the Data and System.Activities.Variable respectively. Like I said translate Data to Variable is just the tip of the iceberg because I might use Data.Get() in my code and don't know how to translate it to Variable.Get(context) while doing the translation.
Solutions that I've tried or thought of:
Solution 1
Instead of a direct translation of properties I would develop NativeActivites for each flow-control activity(If, Sequence, Switch, ...) and make use of CacheMetadata() function to specify Arguments and Variables. The problem remains because they are both accessed through var.Get(context).
Solution 2
Give my Data class its own Get() function. It would be only an abstract method, without logic inside that it would, somehow, translate to Get() function of System.Activities.Variable. Is this even possible using C#? Guess not! Another problem is that a Variable.Get() has one parameter.
Solution 3
The worst solution that I thought of was CIL-manipulation. Try to replace the code where Data/Argument is used with Variable/Argument code. This smells like a nightmare to me. I know next to nothing about System.reflection.Emit and even if I learn it my guess is that it would take ages ... and might not even be possible to do it.
Sorry if I ended up introducing a bigger problem but I'm really stuck here and desperately needing a tip/path to go on.
This is called "duck typing" (if it looks like a duck and quacks like a duck you can call methods on it as though it really were a duck). Declare myObject as dynamic instead of as a specific type and you should then be good to go.
EDIT: to be clear, this requires .NET 4.0
dynamic myObject = new FirstObject();
// do stuff
myObject = new SecondObject();
// do stuff again
Reflection isn't necessarily the right task for this. If SecondObject is out of your control, your best option is likely to just make an extension method that instantiates a new copy of it and copies across the data, property by property.
You could use reflection for the copying process, and work that way, but that is really a separate issue.
I have this code:
public class EntityMapper<T> where T : IMappingStrategy, new()
{
private static T currentStrategy;
public static T CurrentStrategy
{
get
{
if (currentStrategy == null)
currentStrategy = new T();
return currentStrategy;
}
}
}
Then:
public static void Main()
{
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
EntityMapper<ClientMappingStrategy>.CurrentStrategy.ToString();
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
}
Well, the question is:
Why when i'm debugging i can see that the constructor of ServerBussinessMappingStrategy is called only once time?
This work well, but i undertand why always EntityMapper return the correct instance that i need, only instantiating once time the ServerMappingStrategy class.
Regards!
PD: Sorry my english jeje ;)
The static field is persisted for the duration of your AppDomain, and it is cached when first created:
public static T CurrentStrategy
{
get
{
if (currentStrategy == null) // <====== first use detected
currentStrategy = new T(); // <==== so create new and cache it
return currentStrategy; // <=========== return cached value
}
}
Actually, there is an edge case when it could run twice (or more), but it is unlikely.
This is a pretty common pattern for deferred initialization, and is used pretty much identically in a number of places in the BCL. Note that if it had to happen at most once, it would need either synchronization (lock etc) or something like a nested class with a static initializer.
Normally, it will only get called once. That is, unless you have a race condition.
Let's say two threads execute this statement the same time:
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
Let's say thread A will run up until currentStrategy == null but gets paused before new T() when Windows suddenly gives control to thread B which then makes the comparison again, currentStrategy is still null, invokes the constructor and assigns the new instance to currentStrategy. Then, at some point, Windows gives the control back to thread A that calls the constructor again. This is important because normally static members are (sort of) expected to be thread safe. So if I were you, I would wrap that bit into a lock clause.
P.S. this snippet won't compile as T might be a struct that cannot be a null. Instead of comparing to null, compare to default(T) or specify that T has to be a class.