Im working on a custom file explorer, like Wondows Explorer, the problem is that i use for navigation a ListView and a TreeView:

to add items to ListView and TreeView i use the same code but different types: ListViewItem and TreeNode but they have the same properties. I have two solution and dont know what to choose.
Using reflection with something like:
private T AddItem<T>(T parent, string path, string text)
{
...
Type type = parent.GetType();
type.GetProperty("Tag").SetValue(parent, path, null);
type.GetProperty("Text").SetValue(parent, text, null);
type.GetProperty("ImageIndex").SetValue(parent, GetImageIndex(path), null);
...
return parent;
}
public int GetImageIndex(string path)
{
int imageIndex;
string imageHash = NativeMethods.GetAssociatedIconHash(path).ToString();
if ((imageIndex = ilListIcons.Images.IndexOfKey(imageHash)) == -1)
{
ilListIcons.Images.Add(imageHash, NativeMethods.GetAssociatedIcon(path));
imageIndex = ilListIcons.Images.Count - 1;
}
return imageIndex;
}
lvNav.Items.Add(AddItem(new ListViewItem(), ..., ...);
tvcNav.Nodes[...].Nodes[...].Add(AddItem(new TreeNode(), ..., ...);
Or Using inheritance and write "some" code:
interface INavItem
{
string Text { get; set; }
object Tag { get; set; }
...
}
class ListViewItem : System.Windows. ... ListViewItem, INavItem
{
...
}
class TreeNode : ..., INavItem
{
...
}
private T AddItem<T>(T parent, string path, string text) where T : INavType
{
...
parent.Text = text;
parent.path = path;
return parent;
...
}
I know, i know... the answer is quite obvious why use reflection, in this case performance is important, but still without reflection i need to write new clases..., so what do you think?
-
-
Ion Todirel wrote:
I know, i know... the answer is quite obvious why use reflection, in this case performance is important, but still without reflection i need to write new clases..., so what do you think?
Adding an interface to a class is relatively easy. Reflection will be dramatically slower when you come across a long list of items to add to the views.
Reserve reflection for cases where there's no other option -- don't abuse it for coding shortcuts. I've seen some really bad .NET UI code that used reflection and it ran really slowly (click button, ... wait ... , see result).
Herbie
-
Wouldn't it be easier if you just provided 2 AddItem methods?
ListViewItem AddItem(ListViewItem parent, string path, string text);
TreeNode AddItem(TreeNode parent, string path, string text); -
TommyCarlier wrote:
Wouldn't it be easier if you just provided 2 AddItem methods?
ListViewItem AddItem(ListViewItem parent, string path, string text);
TreeNode AddItem(TreeNode parent, string path, string text);
But then you wouldn't get to use polymorphism and make a cool inheritance diagram.
Herbie
-
I think if you use reflection, you will write more ugly and most imprtantly slow code.
Sheva -
I think the answer is Databinding.
-
Use the inheritance model definately. Using interfaces will enforce type safety and yield dramatic performance benefits. Plus you will get compile time checking.
If for example you need to rename one of the common properties that you are setting, and you forget to rename the the property in one of the classes, then the reflection code will compile and execute yet will throw an exception at runtime. However, using the interface model the code will not compile untill all the classes have their properties renamed.
Compile time checking will save you hours of debugging headaches that might occur if accidentallly the class got deployed without having it's property renamed.
-
codewiz wrote:Use the inheritance model definately. Using interfaces will enforce type safety and yield dramatic performance benefits. Plus you will get compile time checking.
If for example you need to rename one of the common properties that you are setting, and you forget to rename the the property in one of the classes, then the reflection code will compile and execute yet will throw an exception at runtime. However, using the interface model the code will not compile untill all the classes have their properties renamed.
Compile time checking will save you hours of debugging headaches that might occur if accidentallly the class got deployed without having it's property renamed.
I agree with this post here. -
-
If .Net supported C++-style templates this wouldn't be a problem.

-
what do you mean?Sven Groot wrote:If .Net supported C++-style templates this wouldn't be a problem.
-
Ion Todirel wrote:
what do you mean?
Sven Groot wrote: If .Net supported C++-style templates this wouldn't be a problem. 
Unlike with .Net Generics, C++ templates don't care at all about the type of the template parameter and won't check if the operations you do on it are actually valid until the moment they're instantiated. THis means you could do something like this (assuming these were native C++ types):
template<typename T>
T& AddItem(T &parent, const std::string &path, const std::string &text)
{
...
parent.Tag = path;
parent.Text = text;
...
return parent;
}
The real cool thing is, C++/CLI lets you do this with .Net types as well:
template<typename T>
T^ AddItem(T ^parent, System::String ^path, System::String ^text)
{
parent->Tag = path;
parent->Text = text;
return parent;
}
But templates such as this are instantiated by the compiler so you can't put them in a class library, and C# has no equivalent functionality.

Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.