|
Thank u
|
|
|
|
|
Hi everyone. I'm trying to invoke a constructor through reflection, with no luck.
Basically, I have an object that I want to clone, so I look up the copy constructor for its type and then want to invoke it. Here's what I have:
public Object clone(Object toClone) {
MethodBase copyConstructor = type.GetConstructor(new Type[] { toClone.GetType() });
return method.Invoke(toClone, new object[] { toClone });
}
I call the above method like so:
List<int> list = new List<int>(new int[] { 0, 1, 2 });
List<int> clone = (List<int>) clone(list);
Now, notice the invoke method I'm using is MethodBase 's invoke. ConstructorInfo provides an invoke method that does work if invoked like this:
return ((ConstructorInfo) method).Invoke(new object[] { toClone });
However, I want to use MethodBase 's method, because in reality instead of looking up the copy constructor every time I will store it in a dictionary, and the dictionary contains both methods and constructors, so it's a Dictionary<MethodBase> , not Dictionary<ConstructorInfo> .
I could of course cast to ConstructorInfo as I do above, but I'd rather avoid the casting and use the MethodBase method directly. I just can't figure out the right parameters.
Any help? Thanks so much.
modified on Wednesday, March 31, 2010 4:07 AM
|
|
|
|
|
Dunno. If casting works, you might as well do that.
Also, why not make the method generic?
|
|
|
|
|
PIEBALDconsult wrote: If casting works, you might as well do that.
Well, I know I can, but I don't want to. This method will be called pretty often and I don't want to be doing any unnecessary operations (such as casting) that may impact performance.
PIEBALDconsult wrote: Also, why not make the method generic?
How will that help? Can you be more specific?
Thanks.
|
|
|
|
|
blackblizzard wrote: unnecessary operations
That type of casting isn't an operation.
blackblizzard wrote: How will that help?
The caller won't have to cast the result; it would be done internally.
blackblizzard wrote: will be called pretty often
With how many different types of object? If only a few, then maybe write specific cloners for them.
|
|
|
|
|
PIEBALDconsult wrote: That type of casting isn't an operation.
I'd say it is. "A cast explicitly invokes the conversion operator from one type to another. (...)"[^]. It results in a IL cast class[^] instruction. How is it not an operation?
PIEBALDconsult wrote: The caller won't have to cast the result; it would be done internally.
I still don't see that. We're always casting to ConstructorInfo. I think you're confusing the type of the object we want to clone, which may be anything, with the type of the method we use for cloning, which may be either ConstructorInfo or MethodInfo (both of which are subclasses of MethodBase) and isn't known a priori, since it depends on whether the type of the object has a copy constructor. Or maybe I'm the one that is confused; in that case please explain.
PIEBALDconsult wrote: With how many different types of object? If only a few, then maybe write specific cloners for them. With any type of object. It isn't known a priori. If it was I would already know whether the types of the objects have copy constructor or Clone methods, and this wouldn't be a problem.
|
|
|
|
|
In many cases (like yours) no conversion is necessary; if I have an instance of class X, but pass it in as Object, and cast it back to X, then there is no conversion -- that's what I meant.
blackblizzard wrote: depends on whether the type of the object has a copy constructor
I don't think you said that originally, but I see what you mean.
I also tested it and see that you are correct; Invoke doesn't seem to behave as documented. Now I'm intrigued...
|
|
|
|
|
PIEBALDconsult wrote: In many cases (like yours) no conversion is necessary; if I have an instance of class X, but pass it in as Object, and cast it back to X, then there is no conversion -- that's what I meant.
Ah, alright. Well, that's good news. Although I'd still like to know how to do it without the cast, just for sake of knowing
PIEBALDconsult wrote: I don't think you said that originally, but I see what you mean.
True, I didn't. I didn't want to include extraneous info, and I was asking something very specific... But yeah, I forgot you didn't know about that.
PIEBALDconsult wrote: I also tested it and see that you are correct; Invoke doesn't seem to behave as documented. Now I'm intrigued...
Great. Now that makes two of us
|
|
|
|
|
blackblizzard wrote: I'd still like to know how to do it without the cast
I tried to write overloaded methods -- one for ConstructorInfo, one for MethodInfo -- but it didn't compile; it might with C# v4.0
Still, even if it worked there'd be the extra method call which would likely be slower than the cast.
|
|
|
|
|
Aha! It is documented:
"
Return Value
Type: System..::.Object
An object containing the return value of the invoked method, or nullNothingnullptra null reference (Nothing in Visual Basic) in the case of a constructor.
"
So I think you have to cast.
Here's a little something I whipped up to show a generic method to do it:
private static readonly System.Collections.Generic.Dictionary<System.Type,System.Reflection.MethodBase> dic ;
static Test
(
)
{
dic = new System.Collections.Generic.Dictionary<System.Type,System.Reflection.MethodBase>() ;
return ;
}
public static T
Clone<T>
(
this T Source
)
where T : class
{
System.Type t = typeof(T) ;
System.Reflection.MethodBase m ;
if ( !dic.ContainsKey ( t ) )
{
System.Type[] part = new System.Type[] { t } ;
m = t.GetMethod ( "Clone" , part ) ;
if ( ( m == null ) || ( ((System.Reflection.MethodInfo) m).ReturnType != t ) )
{
m = t.GetConstructor ( part ) ;
if ( m == null )
{
throw ( new System.Exception ( "blah blah blah" ) ) ;
}
}
dic [ t ] = m ;
}
else
{
m = dic [ t ] ;
}
T result ;
if ( m.IsConstructor )
{
result = (T) ((System.Reflection.ConstructorInfo) m).Invoke ( new object[] { Source } ) ;
}
else
{
result = (T) m.Invoke ( Source , new object[] { Source } ) ;
}
return ( result ) ;
}
|
|
|
|
|
PIEBALDconsult wrote: An object containing the return value of the invoked method, or nullNothingnullptra null reference (Nothing in Visual Basic) in the case of a constructor."
So I think you have to cast.
Ah, I see. That's a bit weird, IMHO, but there you go . Good to get that out of the way, thanks for the info
As for your code, yep, that's pretty much what I was doing except for the generics. However the caller doesn't know the type of the object it's going to clone, so I'll keep it non-generic. But thanks for the alternative
Finally, they gave me a very good answer at Stack Overflow[^] using Func<,> instead of MethodBase . It's way more elegant (and very probably more efficient) so I'm adopting that solution.
Thanks for your input
(so many smiley faces! but there you go)
|
|
|
|
|
Hi,
I use VS2010 + windows forms for a few months, so i can't try WPF, my application is too developped to start from 0.
So I would like to know how to totally edit the skins of combobox, buttons...
To not have windows XP's theme for example.
For example, if I have all my design on Photoshop, I should edit skins of combobox in order to do the same as the design.
I've seen some application which were doing that, but they were really expensive.
So I ask you: How i can create a skin? or edit vista's Style, to have a comboBox totally personnalized.
Thanks.
|
|
|
|
|
[^]
Dear friends
How to send group mail using c# coding.
Sir/Mam,
I'm Kannan.I Like very much for the coding for the project
THANKNG YOU
KANNAN
modified on Tuesday, March 30, 2010 7:37 AM
|
|
|
|
|
If you want to send a mail to group in that case the group should have a defined email address in the Global Address List. Set the group email address in To list of the email.
If you are looking for code to send email using c# then you can check this article in CP
Send mail through C#[^]
WWW, WCF, WWF, WPF, WFC .... WTF
|
|
|
|
|
If you are building a windows app, see here[^].
Me, I'm dishonest. And a dishonest man you can always trust to be dishonest. Honestly. It's the honest ones you want to watch out for...
|
|
|
|
|
|
hello
I've couple core 32 bit dll - trying to package them under a Windows Service running on 64 bit Windows. Is this feasible?
Thanks
dev
|
|
|
|
|
A 32 bit application can run on 64-bit windows, these applications are handled in a different way, but the communication between 32-bit and 64 bit modules can’t happen directly (You need to do some workaround for that). It will be better if you try to migrate it to 64-bit.
WWW, WCF, WWF, WPF, WFC .... WTF
|
|
|
|
|
Change the platform of your service to x86 (instead of Any CPU or x64), then you will not have those communication problems with the 32 bit dlls.
|
|
|
|
|
my application exports a .doc file.. I want to know can I check if any .doc application was installed, eg MS Word, OpenOffice, etc...
|
|
|
|
|
1- Check for the registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Office , if this exists then MS Office is installed in the system or you can check if WINWORD.EXE file exists.
2- For wordpad check WordPad.exe .
3- Same approach you can use for open office, for Open office there must by some executable file.
WWW, WCF, WWF, WPF, WFC .... WTF
|
|
|
|
|
I am using this code to open an adobe reader document but I want to know how can I set the start size to maximized?
Process.Start(Application.StartupPath + "\\Bahrain2030_English.pdf");
|
|
|
|
|
Based on the following, it doesn't seem like you've got anything provided via command arguments (Adobe Reader[^]).
It looks like you'll have to find the reader process and using pinvokes (like this[^]) to maximize the window.
|
|
|
|
|
try something in this format:
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(Application.ExecutablePath + "\\Bahrain2030_English.pdf");
info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
System.Diagnostics.Process.Start(info);
|
|
|
|
|
I am uisng this code to read a specific node from XML using XMLDocument but I want to use the Dataset.ReadXML and want to know how can I do the same but using Dataset?
Save the Value to XML:
resume_xml_document.SelectSingleNode("/Resume/Detail/FullName").InnerText = PersonalInfoForm.txtFullName.Text;
Getting the Value from XML:
txtFullName.Text = resume_xml_document.SelectSingleNode("/Resume/Detail/FullName").InnerText;
|
|
|
|
|
Greetings, all...
I'm using Visual Studio 2008 Express with C# and SQL Server 2008 backend. I'm wanting to design a lookup table form where the user can select the table from a list of items on the left (probably a TreeView with a node for each entry), then have the grid on the right reflect the contents of that table (Users, Config settings, Security, etc.). But I don't have to have a table adapter for each table that could be on the form and would like to re-use the component by setting the properties on the fly. Has anyone done this before?
As a corrolary to this, if the user double-clicks on an entry in the grid, I would like to pop-up a form to allow the user to edit that entry. Again, I would like to use a single form to do this, without having a different form and table adapter, binding source, etc., for each possible table.
Has anyone done this before and can offer any suggestions? Or would the code to do it all run-time outweigh what it would take to just have separate table adapters and forms for each possible lookup table?
Thanks in advance!
- Bert
|
|
|
|
|