β User defined Exception Handling
Why do i get a
"An object reference is required for the non-static field, method, or property 'ReadTextFileMenu.ReadTextFile()'
error?88 Replies
because
TextFileReader.StreamTextFile(filepath);
looks like a static invocation
when you invoke a static method, you do so by ClassName.MethodName()
for an instance method, you need a class instance
example:
Hmm
I'm not sure i'm following. The method inside
ReadTextFileMenu.cs
named ReadTextFile
. If the if statement triggers, it will throw an exception i created. Type out the message and then restart the method ReadTextFile()
Static method and instance method are new conceptswhy would it restart? I see no such code.
and this code is unrelated to your error
I was hoping
ReadTextFileMenu.ReadTextFile();
would make it restartoh dear god
I see now
oh my
this is very cursed. Congratulations, I've never seen this before π
okay, I see what you were trying to do, but using exceptions like this is not the way to do it. but no worries, we can quickly sort up the confusion
first, an
Exception
should only contain information about the error that occured, it should not try to fix it
(thats what the catch block is for)Oh
second, never do input/output code inside a constructor, but especially not in an exception constructor
You knew some C, right?
Is that the text inside
base ()
?
Yeah i know Cno, thats just calling the base exception handler
so you've heard about
while
and for
, right?Yea
great
I'd say
while
is a fairly appropriate tool here
you want to ask the user for a valid path while the current path is not valid
does that make sense?Yeah i think i know what you mean. While the input from the user isn't valid, redo it
throwing exceptions is usually the answer to the problem "I know there was an error, but I don't have the ability to handle it in my current scope. I should let someone else above me know there was a problem, and let them decide what to do"
so for example, if the menuitem code is responsible for asking for the path, but the path is only validated inside the
ReadFromTextFile
method you made before, thats where an exception could be used
"Oh, this method might throw, so I need to handle the path being invalid. And if it was, I'd probably just wanna ask again, so lets put it all in a loop"Hmmm
I guess this was not how you meant? Considering i'm getting the same problem :catlaugh:
you'd need to remove the
throw new...
line hereYeah i realized the code below becomes unreachable
Ok the while loop works now. But it's not triggering the exception
well yeah, we removed the exception
The goal is to make a user defined exception for practice
oh okay
This would be my constructor for my exception?
yes
Inside the
{}
what would go there?that error message should not include instructions to the user, btw
exceptions should not be shown to users, they are intended for the programmer or an error log file
Ohh i see
most of the time, nothing. If your exception contains detailed information about the error, like an error code, or stuff like that, you might put it there
for example:
I updated it. So something like this is more appropriate?
this would not be out of place at all in an exception based around files
Sure, that could work. Its a bit verbose and "friendly", which is unusual for exceptions but it works
A more common message might be "Specified path '{path}' does not exist"
but what you wrote is fine too π
So now i include an
if
to check if the filepath does exist, and throw an exception?from your previous thread, you used to have 2 methods right?
the menu item, and your own stream-file-reader thing
Ah that was a different namespace
not working on that problem anymore?
if you want to demonstrate proper usage of exceptions, I suggest you throw the exception in the file-reading method, and handle it in the menu item method
exceptions are rarely (never?) used to handle errors within the same method that made them - because if you CAN do that, you can handle it without an exception
No i finished it. It works as intended. The next part is :
"In the file FileDoesNotExistException.cs (in the folder Exceptions), there is a code skeleton for
the class FileDoesNotExistException. Use this class to implement a user-defined exception
that can be thrown if the text file in Chapter 2 doesnβt exist in the file system. The exception should
contain an error message and the path to the non-existent file. Then modify the code in the class
TextFileReader (Chapter 2), so that the exception is thrown if the text file doesnβt exist "
exceptions unique ability is to "bubble up" (move upwards) in the call stack
okay
so theres nothing there about catching the exception, might that be the next step?
Ah crap the exception should be thrown in the TextFileReader.cs and not in the menu
yeah that makes more sense π
Alright i see. So they want me to catch the exception here with my own user defined exception
Damn i can't seem to find a solution. My program stops completely but in my teachers code which is nearly identical they get to try again
can you show me your latest code, both files?
That seems fine
now show me your menu code
It stops the program at
if (!File.Exists(filepath))
{
throw new FileDoesNotExistException(filepath);
}
yes
your menu code does not use
try/catch
so it just crashesI'll try and add that
okay i think i did it!
I added this try and catch
almost!
see, that
ReadTextFile();
down there will actually cause issuesOh i see. What happens after a catch has been found? Does it restart automatically?
calling a method from itself is called recursion
no, it runs the code in the catch then nothing
if you want to restart, you must manually do that
let me show you
Oh interesting
I manually added the recursion there such that the program doesn't just end if the user inputs a filepath that doesn't exist.
Is recursion ok in c#?
I'm very used to it in C
its generally avoided
definately do not use if a normal loop does the trick
its very useful for stuff like traversing a tree, or pathfinding etc
because otherwise, imagine if I am a silly user and I keep entering a bad path
it doesnt "restart" the method, it runs the method again, in a new stack frame
meaning...
Oh yeah crap yeah i can def see an issue with that
every time you "restart" you actually open a new frame, further down the stack
Aahhh okay that makes sense now. I read through the code and with the
Show()
I can actually just view all the options again from the menu in the same Frame
So i just simply got rid of the recursioncan you?
show me
Show comes from the base class, but I would guess it invokes the command action for the menu item somehow
Im pretty sure you are creating another frame here too
RIp :catHeyHello:
read my age example with John again
and you'll figure it out
That was my teachers solution xD
Oki 1 sec
your teacher is a hack, we already knew this π
Quick question. What does the
public int Age { get; }
and Age = age;
do?the first declares a property. its an instance member variable that normally holds public information. in this case, its read only (no setter)
Age = age
sets the value of the Age property to the value given to the constructor
I just wanted to show that the main benefit of making your own exceptions is that you can include actual data inside them
not just a messageAh yeah
Hmm i'm not entirely sure i understand the first part.
public TooYoungException(int age)
I get that this is a method that accepts the argument int age
public int Age { get; }
this however hmmwell you know how you must declare a variable before you can use it?
It defines a read only property?
Would this be a struct?
this is declaring a property, which is a form of instance member
Right yeah you got to declare a variable before you can use it
In this case it's name is
Age
.this is just like that, but instead of a local variable that only exists inside a method, this is an instance member
meaning it will "keep" the value for as long as the instance lives
so for this particular exception instance, it will have this Age value
if I make another instance, it has its own Age
Ahhhh so the
get
that you use indicates that it's only a getter? i.e can't be changed only used?correct!
Neat
you might have seen
{ get; set; }
beforeYeah litearlly 5 minutes ago hahah, just read up about them
thats "both a getter, and a setter"
But yeah that makes a lot of sense
there is also
{ get; private set; }
which means anyone can read, but only I can writeIn my own mind i'd like to do
public int age;
But i'd assume this would be both a getter and setter?that would be just a field
a field doesnt have the concept of having getters or setters
thats why we dont use them for public things
In C if i do
int age;
it would get a garbage value, deos this apply to c# also?no
you'd just get an uninitialized variable, which cant be used in C#
I see
C# has a runtime, so its not like C that just runs machine code
so no "use after free" etc
I'm pretty sure C# uses machine code also?
not directly
C# does not compile to native machine code
Ah it had something to do with .NET compiling
iirc
yeah
public int Age { set; }
Does this even have any use? Only being able to set a value without retrieving it sounds dumbthat has essentially no value, correct
but regarding machine code, C# did quite recently get the ability to do "AOT compilation"
this does result in machine code, but its... its complicated π
:catlaugh:
I'm gonna continue with the program now. With writing this time... will open a poster later if something comes up
thanks again (: