I have a class that is called regularly by several objects.
I would like to include information in any exceptions as who the creater of the object is.
What are my options?
"Who" refers to an object or class
Store a stacktrace when the constructor is called. This is similar to what SlimDX does in debug builds.
I might be missing something, but I am pretty sure that the only way you can do it, is by manually passing this information, fe. in constructor of your object.
Edit : If this is what you were looking for? :
class Creator
{
public string Name { get; private set; }
public Creator(string name)
{
Name = name;
}
}
class Foo
{
readonly Creator creator;
public Foo(Creator creator)
{
this.creator = creator;
}
public void DoSth()
{
throw new Exception("Unhandled exception. My creator is " + creator.Name);
}
}
public static void Main()
{
Foo f = new Foo(new Creator("c1"));
f.DoSth();
}
If it's only for debugging purposes then add a local string field to the class and assign Environment.StackTrace to it in the class constructor. Then you can include the information in the exceptions as well.
One choice would be to put a "parent" reference into the object:
MyObject myObj = new MyObject(this);
and then use that.
You can try to gather some information from the stack trace in the constructor of your object. You can get the stack frames StackTrace.GetFrames. Then you can walk the stack and try to get the type that a method belongs. If that type is different than the type of your object, you stop walking and store that type information within your object. Then when an exception occurs, you can include that information along with the exception.
Note that this will increase the cost of instantiating your object. So you should consider that and may be put in a mechanism to enable/disable it or include that piece of code only in the debug build.
The question is slightly ambiguous; it really depends what you want. Is this debug information for debug builds, or is it something you will always keep around?
If it's just debug cruft that will be removed in the released product, I'd suggest doing something like this to reduce the pollution of your class(es):
Move the creation into a factory and put the stack inspection code there. This way, the created class doesn't need to care about the stack frame stuff; it is hidden away in the factory.
You can then inject the information via a property setter if you don't mind a little pollution or you could have the factory update a list of created instances + associated creation information for each instance. You can then query this list til your heart is content. Finally, in the release build, you can remove all of this functionality with a couple of #ifdefs.
I'd recommend using the StackTrace object and/or it's GetFrame method. I haven't tried it but it should do what you need it to do w/o having to change every instantiation of the object (assuming you're not using a Factory).
I would imagine something similar to this would work.
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Also note that this appears to be "not quite" a duplicate, but it's close to the question linked above.
Something like this could work to get the calling type:
public class Foo
{
private Type ParentAtCreation = null;
public Foo()
{
ParentAtCreation = (new StackTrace())
.GetFrame(1)
.GetMethod()
.DeclaringType;
}
}
You can use overloaded constructor to that class and a global variable to store that object you receive in that overloaded constructor
e.g if you want an object of class in winforms when you invoke the object to be created you use a overloaded constructor that receives an object of a form
and in the constructor you use this object to store its value in global variable like
When you declare the object as in this case i use a form to open using my currently running form then
Admin_Login ad = new Admin_Login(Enrol, this);
ad.Show();
this.Visible = false;
and make the current form not visible to invoke it again when i want it. I cant dispose it as its the parent of the new form now
and in Admin_Login form i have an overloaded constructor
public Admin_Login(string Enrol,Form parent)
{
Enrollment = Enrol;
Parent = parent;
InitializeComponent();
}
where Parent is my global variable of Form
B.O.L
I'm surprised no one else has said this yet, even as a caveat to their own solution, so I will: this is generally a bad idea, and if you find yourself needing to do it, that's usually a huge indicator that something is very wrong with your design. If you go down this route to solve your problem, you will end up causing far larger issues down the road. Best to take 2 steps back and fix the design that is making this necessary.
Related
Is it possible if we delete an object from the class itself? I have a class like below:
Parent Class:
public class ModelBase<T>
{
.....
public void Delete()
{
this = null // <-- it's not works
}
.....
}
Children Class:
public class Company : ModelBase<Company>
{
public string Name;
public Company(string name)
{
Name = name;
}
}
Declaring on UI Layer:
var company = new Company("Company X");
Console.WriteLine(company.Name);
company.Delete();
Console.WriteLine(company.Name); // <-- this should be empty or null
Deleting the object should be on parent class. Is it possible to do that?
No, in C# the garbage collection does the "deleting" for you eventually.
If there`s something inside the class you want to manually dispose like a connection you can use the Disposable Pattern (https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern).
The closest you can come to manually deleting the object is forcing the garbage collector to collect with GC.Collect (https://msdn.microsoft.com/en-us/library/xe0c2357(v=vs.110).aspx).
Obviously setting this to null inside Delete function has not effect outside of the function (if it ever compile).
Destroying an object from itself is also very dangerous as you would have to be sure that no code afterward would access that object (or the caller stack). IN fact, in C#, the idea does not make more sense as it is garbage collected which imply that if you are inside a member function, then you have at least one reference to the object in which case it would never be garbage collected at that point anyway.
Also assuming that the object company was destroyed (and company set to null), you would get a null pointer exception when calling .Name.
Assuming that company object is not disposable (does not implement IDisposable), then your code should look like:
var company = new Company("Company X");
Console.WriteLine(company.Name);
company = null;
Console.WriteLine(company?.Name); // <-- this should be empty or null
Well, we assume that real code is somewhat more complex than that as otherwise you could simply replace last line by:
Console.WriteLine();
However if you company object implement IDisposable, then usually you should use the using keyword if which case setting the object to null would not make sense.
using (var company = new Company("Company X"))
{
Console.WriteLine(company.Name);
}
Console.WriteLine();
Your Delete function is really a bad idea and clearly show a lack of understanding of C#.
If you want to know if an object has been destroyed, you could use WeekReference. As an example, it can be used for a cache. See reference documentation for more information: https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx.
Your whole code make little sense. If you have only one variable, then it is trivial for a decent programmer to know when the object is alive. If you have multiple objects, then you should use a collection (for ex. List<Company>) in which case, you would obviously remove a company from the collection if you don't want it anymore and then when you use that collection, you would not see it anyway.
Alternatively for complexe cases, you might use a dictionary, a set or a flag to remember if you should process a given object. This might be useful for example when iterating a collection as usually you should not modifying while you are enumerating its items.
In the perspective of callbacks, I am facing a strange situation when I knew that myDelegate.Target contains the reference to the class whose method it contains. (I searched it on SO, however I excuse if I missed some thread already answering this)
For example
public delegate void TravePlanDelegate();
public class Traveller
{
//Papa is planing a tour, along with Mama
public void Planner()
{
//Asking me (delegate) to hold a letter about PlanA's detail
TravelPlanDelegate myPlan = PlanA;
//Sending me to TravelAgency office with letter
new TravelAgency().ExecuteTravelPlan(myPlan);
}
public void PlanA()
{
//Papa's open plan with Mama
Console.WriteLine("First Berline, then New Yark and finally Lahore");
}
public void PlanB()
{
//Papa's secret plan
Console.WriteLine("First Dubai, and then Lahore");
}
}
public class TravelAgency
{
public void ExecuteTravelPlan(TravePlanDelegate tp)
{
Traveller traveller = (Traveller)tp.Target;
//Here it should execute plan
//tp.Target - A reference to Traveler class, which can lead travel
//agency to Papa's secret plan (And exposes it to Mama)
}
}
In this example, TravelAgency can get information from delegate about papa's secret plan too. Did I get delegate concept properly or missing something?
Your assumption is correct. Unfortunately, however you try to "encapsulate" your object- there must always be a reference to it somewhere, otherwise it would be impossible to invoke it's instance method.
As some kind of counter measure, you can proxy the method invocation to a lambda expression:
TravelPlanDelegate myPlan = (args) =>PlanA(args);
This makes it less likely that any rogue code will attempt to carry out some ill intended operations on your code, since knowing how your code looks like in advance will not help it accomplish a thing.
Note that this does not ensure a thing, since the produced delegate still has a Target property to an object which holds a reference to yours.
Crackers which are smart enough can still apply reflection to the generated class and obtain a reference to your object.
Conclusion:
Only consume code you trust - it is not much of a problem in today's Open Source driven world.
What is the best way to initialize static fields via a static init method and afterwards make sure that the method is never called again? (no more than once during the lifetime of the program)
This is an example of what I currently thought of, it seems pretty simple to me but I couldn't find any examples of similar patterns that deal with this:
class Entity
{
static Manager manager;
static bool isInitialized;
public static void Initialize(Manager manager)
{
if (isInitialized)
throw Exception("Class Entity already initialized."
+ "Do not call Entity.Initialize() twice.");
isInitialized = true;
Entity.manager = manager;
}
}
What is the best way to initialize static fields via a static init method and afterwards make sure that the method is never called again?
Do you really have to do this? Why do you not want to create an instance of Manager and make it available to code which relies on it through dependency injection? That would make your code much cleaner:
You'd allow it to be testable with different initialization paths
You wouldn't need any checking for "bad" duplicate initialization
You wouldn't need to structure your calling code to specify a single initialization point for this class. (You may need to do something similar for the IoC container of course...)
You'd allow your code which depends on it to be more testable too
The code which depends on Manager would be express that dependency in a clearer way
I suspect you haven't found any similar examples because it's an anti-pattern.
If you do go for your current approach, you should really try to make it thread-safe, too...
Don't over think it, if that pattern works for you, go with it. There isn't always a "right" answer, and trying to stick to rigid patterns and practices just for the sake of sticking to them is not a good idea either. IMHO.
Sorry for stating the obvious, but you could use the object initializer or the static constructor. Besides that, you can just not call the method. Seriously. Why would someone call a method called initialize anyway.
What you could do is this. You can hide the method from IntelliSense and similar with this attribute. Stops it from cluttering up the dropdown too
Your implementation is not thread-safe, but is otherwise reasonable. If it's intended for use in a multithreaded environment, add locking.
In your sample, the open question is what should happen if multiple callers (possibly from multiple threads) call the initialization method with different parameters. This is what makes your pattern unusual, and prevents you from using the obvious static constructor or object initializer.
Can't you just use a static constructor?
Of course, you do not have control over when this constructor is called, but don't know if this is a requirement.
http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx
You might want to use a singleton pattern with parameters to only expose certain functionality of the Manager variable.
class Entity
{
private Manager _manager = null;
public Manager manager
{
get
{
return _manager;
}
set
{
if (manager == null)
{
_manager = value;
}
}
}
/* rest of class */
}
Now you can use the manager object as any variable, but repeated sets will not modify the value.
this.manager = new Manager(0); // sets the manager
this.manager = new Manager(1); // does nothing
Now to complete the pattern in your constructor somewhere or at some reset function you might want to do a
this._manager = null;
I have a quite large project which I try to keep as clean and tidy as possible. When I run the code analyzer in Visual Studio I get a reliability error which I find quite annoying. I'd really like to learn how to work around it. Here is a simplified example of what I am doing.
Here is the warning.
Warning 1 CA2000 : Microsoft.Reliability : In method 'MyExampleClassForStackOverflow.AddFeed(string)', call System.IDisposable.Dispose on object 'new FeedClassExamle()' before all references to it are out of scope.
Here is my example code:
class MyExampleClassForStackOverflow : IDisposable
{
public ConcurrentDictionary<string, FeedClassExamle> Feeds { get; set; }
public void AddFeed(string id)
{
//The warning is coming from this code block.
//In the full code, the feed classes collects data on a specific
//interval and feeds them back using events.
//I have a bunch of them and they need to be accessible so I
//store them in dictionaries using keys to effeciently find them.
Feeds.TryAdd(id, new FeedClassExamle());
Feeds[id].Start();
}
public void Dispose()
{
foreach (var item in Feeds)
item.Value.Dispose();
}
}
class FeedClassExamle : IDisposable
{
public void Start()
{
}
public void Dispose()
{
}
}
In order to test the code, use:
using (var example = new MyExampleClassForStackOverflow())
{
}
Any suggestion would be welcome.
The warning exists because the code analysis tools can't determine whether the object will get disposed correctly. The way your code is written, the object will not in fact get disposed correctly, but fixing the code will likely not eliminate the warning.
Fundamentally, what needs to happen is for every the AddFeed method to ensure that something will call Dispose on every FeedClassExample instance it creates. The best approach is to avoid creating a FeedClassExample instance if one already exists in the dictonary under the present ID. Failing that, the AddFeed method should either dispose of any FeedClassExample it creates but then decides not to store in the dictionary, or else swap with the one that is in the dictionary (I'm not sure what methods ConcurrentDictionary supports to do that) and then Dispose the old one. The essential requirement is that at all times outside the actual execution of AddFeed, the dictionary will hold all instances of FeedClassExample that have been created but not destroyed.
It may be informative to add a destructor in your FeedClassExample class which does nothing except log a message. If you are calling Dispose on that class correctly, the destructor will never execute. If you fail to call Dispose, it will. Thus, if the destructor ever executes, you can know you're doing something wrong.
The object isn't getting Disposed of if TryAdd fails, so try doing this explicitly:
public void AddFeed(string id)
{
FeedClassExample fce = new FeedClassExamle();
if (!Feeds.TryAdd(id, fce))
{
fce.Dispose();
}
Feeds[id].Start();
}
Only create the instance if it needs to be added:
if (!Feeds.ContainsKey(id)) {
Feeds.GetOrAdd(id, new FeedClassExamle());
}
In an earlier question about how to return a string from a dialog window, yapiskan suggested overloading the child form's ShowDialog() method to include an out parameter.
My question is whether or not this is a good approach in C#.
Here is some example code, based on yapiskan's suggestion. In the child form (in this example, it's a form with a textbox on it), you just need to add the ShowDialog overload and assign UI values to the out parameter:
public DialogResult ShowDialog(out string s)
{
DialogResult result = this.ShowDialog();
s = this.textBox1.Text;
return result;
}
And to show the form and retrieve the entered text, you do this:
using (CustomDialog frm = new CustomDialog())
{
string s;
if (frm.ShowDialog(out s) == DialogResult.OK)
{
// do something with s
}
}
One advantage I can think of is that this approach forces the user of the CustomDialog form to get the information it contains through the form's ShowDialog method (rather than from a who-knows-what-it's-called method like GetMyData() or something).
Better to have a Public property/method and get the information.
What would you do if you would need 3..4..5 informations, having 5 parameters out? More clean to have accessors to get your information from the Dialog.
It should not be OK since .net framework does not use this design. In the case of OpenFileDialog class, it has a parameterless ShowDialog() method returning a DialogResult. Once this method called, user is supposed to get the selected files by using the FileName, FileNames, SafeFileName and SafeFileNames methods.
Let's assume that this implented in the "out parameter" way. I would have to write code like this just to get the SafeFileName:
string dummyFileName;
string[] dummyFileNames;
string safeFileName;
string[] dummySafeFileNames;
myDialog.ShowDialog(out dummyFileName, out dummyFileNames, out safeFileName, out dummySafeFileNames);
Personally I try to avoid out parameters wherever possible, although I understand that like GoTo they are sometimes a necessary evil. I would say that it would be much better to use properties or methods to return the information.
In my experience, a custom modal dialog that collects only one piece of information is a pretty extreme outlier. Much more common are zero and many.
And a dialog that collects many pieces of data is almost certain to be modified at some point to collect just one more. I'd much rather fix only the code that uses that one new piece of data than every single piece of code that uses the modified dialog.
Also, think about how a developer uses IntelliSense to use your class. He's going to type this:
MyDialog d = new MyDialog();
d.ShowDialog(
...and at that last keystroke, IntelliSense will pop up telling him that he now has to declare three new string variables to hold the out parameters. So he moves the cursor up, and starts typing:
string foo;
string
...and, what was the name of the second parameter again? So it's back down to the open paren, hit CTRL+SPACE, oh yeah, it's bar, back up to the previous line, etc.
The problem with using properties on a custom dialog is that the Form class already has a million properties, and the three or four special ones that you're creating are going to get lost in the mix. To fix this, create a class for the dialog parameters and a Parameters property of that type on the custom dialog. That makes code like this easy to write:
MyDialog d = new MyDialog();
d.Parameters.Foo = "foo";
d.Parameters.Bar = "bar";
d.Parameters.Baz = "baz";
because the parameter names pop up in IntelliSense, and you don't need to declare any variables to hold their values.
My approach is typically to write a method that internally calls ShowDialog, then formats the output data appropriately. For (contrived) example:
public string GetFolderName(){
if(this.ShowDialog() == DialogResult.OK) {
return this.FolderName.Text;
}
return String.Empty;
}
In most cases I make this method static, and instantiate the dialog itself from within the body of the method - that way the caller doesn't have to deal with form references, or the notion of having to chose which 'show' method to call.
In the non-edge cases of having multiple output values, I typically construct a struct that holds these values, then have my 'Get' function return that struct.
public struct FolderData {
public static FolderData Empty = new FolderData();
public string FolderName {get; set;}
public int FilesInFolder {get; set;}
}
public FolderData GetFolderData(){
if(this.ShowDialog() == DialogResult.OK) {
return new FolderData {
FolderName = this.FolderName.Text;
FilesInFolder = int.Parse(this.FilesInFolder.Text);
}
}
return FolderData.Empty;
}
I prefer this one because I don't like the approach of getting result from a property or a method after you have done with the class. After dialog form was shown and closed I think the object should not be used any more because logically you have done with the dialog then why should I use its property or method to get the result?
#Musigenesis, you really don't want to force client code to break when you change your dialog, and using an out parameter that is only sometimes valid isn't a good design. As #Daok says, when you have more than 1 value returned this starts to get messy and ugly fast.
You also can't force client code to use the result any more than the .net framework ensures that you call properties on a file dialog. You're also not forcing the caller to do anything with the out parameter, all you've forced them to do is to accept a variable that they may not want to use.
If the dialog is very generic this may not be applicable, but instead of chucking all sorts of properties to the dialog itself, have a single method that you use consistently throughout your application, and have that return a specific class that holds the relevant data.
public sealed class MySaveDialogResult
{
public static MySaveDialogResult NonOkResult(); // Null Object pattern
public MySaveDialogResult( string filePath ) { ... }
// encapsulate the dialog result
public DialogResult DialogResult { get; private set; }
// some property that was set in the dialog
public string FilePath { get; private set; }
// another property set in the dialog
public bool AllowOVerwrite { get; private set; }
}
and your dialog is
public MySaveDialog ...
{
public MySaveDialogResult GetDialogResult() { .... }
}
The essence is a small immutable utility class that also implements null object pattern. The null object is returned whenever the dialog result wasn't OK. Obviously the above is a shot in the dark for your needs, so alter it at will, make inheritance hierarchies, etc.
The main point is to have GetDialogResult(), a single method on the dialog, to returned a class that encapsulates all the relevant dialog data.
edit:
#yapiskan wonders why not just 'out' the MyDialogResult versus calling GetDialogResult().
IMO - The points are simply:
That's not the convention
A method call is trivially easy, and made easier when you follow the 'convention' argument as made above.
out is awkward to use. GetDialogResult() is not forcing the caller to write awkward code, and it doesn't force the user to consume the dialog result at the point of invoking the dialog.
Normally the dialog isn't re-instantiated or re-shown to get the result, it's already there. Show() and Hide() do just that.
The reality is you're trading a method call for an awkward ShowDialog() syntax. Method calls are cheap, and you can't guarantee the caller will use your out parameter any more than you can guarantee they will call GetDialogResult(). So why bother. Make the thing easy to use, or don't overload ShowDialog in the first place.
Maybe whatever you're sub-classing is funky and acts differently and it's not applicable to your situation, but general design is forms don't go away when you click OK, they go away when they are Disposed() of.