|
trinm1987 wrote: Yes, I want to design a program WebBrowser
That's a HUGE undertaking for a single person. It normally takes entire TEAMS of people a few years to write a browser from scratch. Good luck with that...
|
|
|
|
|
public class StatusChangedEventArgs : EventArgs
{
private string EventMsg;
public string EventMessage
{
get
{
return EventMsg;
}
set
{
EventMsg = value;
}
}
public StatusChangedEventArgs(string strEventMsg)
{
EventMsg = strEventMsg;
}
}
public delegate void StatusChangedEventHandler(object sender, StatusChangedEventArgs e);
public static event StatusChangedEventHandler StatusChanged;
Okay, so in the above code, we created a delegate and a custom event.
public static void OnStatusChanged(StatusChangedEventArgs e)
{
StatusChangedEventHandler statusHandler = StatusChanged;
if (statusHandler != null)
{
statusHandler(null, e);
}
}
What does the bold line do? Why do we check for null?
EDIT: The code is from C# Chat: Part 2 - Building the Chat Server (C# Programming Tutorial) • Geekpedia[^] check that out, if the above code doesn't provides what I mean.
|
|
|
|
|
Hi,
you make a local copy of StatusChanged, so the same value gets used both in the null-text and the invocation; StatusChanged is public, so it could be changed by another thread at any point in time; removing the last handler from it right after the null-test got executed would cause an exception in statusHandler(null, e);
In summary, without it your code would not be thread-safe.
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Friday, June 10, 2011 12:01 PM
|
|
|
|
|
so the same value gets used both in the null-text and the invocation;
I'm sorry, but I didn't got it, what do you mean by null-text and the invocation?
I'm converting this code to C++/CLI so I don't know C#, that's why having little problems...
|
|
|
|
|
if (statusHandler != null) <--- that looks like a null-test
statusHandler(null, e); <--- according to the comment this is an invocation
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Friday, June 10, 2011 12:02 PM
|
|
|
|
|
Hmmm, you wrote null-text
lol.. Thanks anyways
|
|
|
|
|
Isn't that just making a copy of the reference?
And therefore no safer than testing/invoking directly on the original reference?
Subvert The Dominant Paradigm
-- bumper sticker, circa 1971
|
|
|
|
|
Yes, it copies a reference, making sure the event and the delegates inside it can not be garbage collected (it is a local copy). There still is a possibility that the event gets changed (it is kind of a linked list), to cope with that you could (probably should) add a try-catch around the invocation.
This is one of those rare cases where an empty catch block would be fine: after all, if another thread is allowed to remove the last delegate, that really means there is no need to call it anymore.
Have a look at the fine article Giorgi provided.
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Friday, June 10, 2011 12:02 PM
|
|
|
|
|
ahhh... reference to empty versus null reference. Got it.
Now I have to rework a whole bunch of code... I foresee a generic solution
Subvert The Dominant Paradigm
-- bumper sticker, circa 1971
|
|
|
|
|
Luc's answer is perfect.
In addition, there's no need to declare your own delegate (from 2.0 onwards). Instead, just declare the event...
public event EventHandler<StatusChangedEventArgs> StatusChanged;
and in the OnStatusChanged...
EventHandler<StatusChangedEventArgs> statusHandler = StatusChanged;
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
|
|
|
|
|
|
Given the following code:
public class Employee1
{
public string Property1 { get; set; }
public Employee1() {}
}
public class Employee2:Employee1
{
public string Property2 { get; set; }
public Employee2():base() {}
}
public class Form1
{
List<employee1> m_employees = new List<employee1>();
private void Add()
{
m_employees.Add(new Employee1());
m_employees.Add(new Employee2());
}
private bool IsType(object item, string typeName)
{
bool result = false;
if (item != null && !string.IsNullOrEmpty(typeName))
{
result = (item.GetType().Name == typeName);
}
return result;
}
}
I want to add the items in this list to a ListView , but I have to cast the objects to their actual types, like so:
string[] listItems = new string[2];
if (IsType(obj, "Employee2"))
{
listItems[0] = ((Employee2)obj).Property1;
listItems[1] = ((Employee2)obj).Property2;
}
else
{
listItems[0] = ((Employee1)obj).Property1;
listItems[1] = "Not applicable";
}
I want something more generic (I want to avoid using the actual type names if possible). I tried to use various properties in the type object returned by Type.GetType("Employee2", true, false); as a casting mechanism, but nothing seems to work.
I want to do something like this:
string[] listItems = new string[2];
Type itemType = obj.GetType();
listItems[0] = (itemType)obj).Property1;
if (IsType(obj, "Employee2"))
{
listItems[1] = ((itemType)obj).Property2;
}
else
{
listItems[1] = "Not applicable";
}
Does anyone have any ideas?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote:
Does anyone have any ideas?
Usually, you do something like this:
Employee2 empl = null;
if (obj is Employee2)
empl = (Employee2)obj;
or you can do this:
Employee2 empl = obj as Employee2;
The latter will return null if obj is not of type Employee2 ;
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
I'm already doing that, and that's what I want to avoid.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Ah, now I understand what you're trying to do.
In this case I don't think you get around some mapping mechanism and reflection, something like (defined in a XML file or whatever):
"Employee2" -> Property1 x Property2
But that still requires some knowledge about the types and properties being used.
Maybe you can use attributes and reflection to get a list of all the necessary properties to take into account when adding them to the listview. Something like this:
[ListViewProps("Propery1", "Not Applicable")]
class Employee1
{
}
[ListViewProps("Propery1", "Property2")]
class Employee2
{
}
And then doing some reflection magic to automatically get the values of the properties
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Not a answer to your exact question, but when I've needed to do this before I add a ToListViewItem() method in the class so each class can do it's thing seperately.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
Sounds like a good solution, although it couples GUI logic with the business logic. I don't think an Employee object should know anything about a ListView
modified 12-Sep-18 21:01pm.
|
|
|
|
|
I agree, but... it's not coupling to the actual ListView, just returning a ListViewItem so it can be dropped into a ListView easily by the presentation layer. Not ideal, but functional.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
I also still have to cast it to the specific type. :/
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Hmmm, good idea. It definitely reduced the amount of code in the form. Instead of creating a ListViewItem object, though, I returned a string array so that using the class doesn't require any more dependencies than necessary (so my method name is actually ToStringArray() .
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
I thing the ToXXXArray method is probably the best way John, but I had another obvious thought this morning. You could use an IEmployee interface with the two properties, and in Employee1 either throw a NotImplementedException (and catch it when building the list - I hate throwing exceptions personally ) or return String.Empty / "Not applicable" for the unused property.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
DaveyM69 wrote: either throw a NotImplementedException
Nah - ugly is as ugly does.
DaveyM69 wrote: or return String.Empty / "Not applicable" for the unused property.
I don't want to introduce interfaces to the group yet. We're training up our COBOL programmers so they can move to .Net/C# with the rest of the dev team via in-house training provided by the experienced .Net programmers we already have (there are four of us, and about a dozen of "them").
I'm giving this week's class, and am recapping what they learned over the last couple of weeks because I want to make sure they understand the fundamentals before we move on. Last week, they were introduced to OOP principals, and given a homework assignment to build an Employee class. They were told about inheritance, encapsulation, and polymorphism, but were not given real examples of those things. I'm starting with their homework assignment from last week, and using a 4-step solution to fully illustrate those concepts.
I don't fully understand interfaces and why they're used yet, but it seems to me that using an interface isn't appropriate because it destroys the object-oriented aspect of the code. (Don't forget, I'm a C++ guy at heart.) Can you give me an example of how an interface would be implemented/used in this particular case?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote: Can you give me an example
Sure... I'll just post working code. Just ask if more clarification is needed, but I think it should make sense.
namespace EmployeeTestApp
{
public interface IEmployee
{
string Property1
{
get;
set;
}
string Property2
{
get;
set;
}
}
}
namespace EmployeeTestApp
{
public class Employee1 : IEmployee
{
private string m_Property1;
private string m_Property2;
public Employee1()
: this("Unknown")
{ }
public Employee1(string property1)
{
m_Property1 = property1;
m_Property2 = "Not applicable";
}
#region IEmployee Members
public string Property1
{
get { return m_Property1; }
set
{
if (m_Property1 != value)
{
m_Property1 = value;
}
}
}
public string Property2
{
get { return m_Property2; }
set
{
}
}
#endregion
}
}
namespace EmployeeTestApp
{
public class Employee2 : IEmployee
{
private string m_Property1;
private string m_Property2;
public Employee2()
: this("Unknown", "Unknown")
{ }
public Employee2(string property1, string property2)
{
m_Property1 = property1;
m_Property2 = property2;
}
#region IEmployee Members
public string Property1
{
get { return m_Property1; }
set
{
if (m_Property1 != value)
{
m_Property1 = value;
}
}
}
public string Property2
{
get { return m_Property2; }
set
{
if (m_Property2 != value)
{
m_Property2 = value;
}
}
}
#endregion
}
}
using System.Collections.Generic;
using System.Windows.Forms;
namespace EmployeeTestApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<IEmployee> employees = new List<IEmployee>();
employees.Add(new Employee1(
"Employee1 Instance, Property1"));
employees.Add(new Employee2(
"Employee2 Instance, Property1", "Property2"));
foreach(IEmployee employee in employees)
{
ListViewItem item = new ListViewItem(employee.Property1);
ListViewItem.ListViewSubItem subItem = new ListViewItem.ListViewSubItem();
subItem.Text = employee.Property2;
item.SubItems.Add(subItem);
listView1.Items.Add(item);
}
}
}
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
But Employee1 has a property, and Employee2 is derived from Employee1 and has a property that Employee1 doesn't have. How is an interface going to help in that case?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|