473,394 Members | 1,870 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Problem with array initialization using Activator.CreateInstance

I'm building some dll assemblies that have in them the implementation of an
abstract class defined in a different assembly.

I'm trying to create objects of the type defined in the dlls with
"Activator.CreateInstance".

Everything was working fine until I started to fill out the class def with
some implementation. At some point the CreateInstance was failing with a
"MissingMethodException - No parameterless constructor defined for this
object".

I tracked down the problem to an array I was creating in the implementation
of one of the methods.

Specifically, if I create my array like this:

byte [] myByteArray = {0xFF, 0xFF, 0xFF};

it will throw an exception. But, if I create it like this:

byte [] myByteArray = new byte[3];
myByteArray[0] = 0xFF;
etc.

It works fine.

I'm a bit puzzled by this. How can all function local code affect the
creation of an object? And why would it make a difference how the array is
created and initialized within a method of the derived class?

Can anyone help clear this up? Am I doing something I shouldn't be?

Thanks!
Nov 15 '05 #1
4 6664
Terry <ch**********@hotmail.com> wrote:
I'm a bit puzzled by this. How can all function local code affect the
creation of an object? And why would it make a difference how the array is
created and initialized within a method of the derived class?

Can anyone help clear this up? Am I doing something I shouldn't be?


<snip>

That sounds very odd to me. Could you provide a short but complete
example which demonstrates the problem?
See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
Ok. Here it is. Here's a simple test case which demonstrates the problem
I'm having. If I'm doing something wrong, please let me know.

There are 3 projects created. One is the "interface dll" which contains the
abstract class. Another is the "implementation dll" which contains a class
that derives from and implements the abstract class. And there's a Windows
forms app to use as the driver. Here are the steps and code.

1. Create a "Class library" project. This will define an abstract class to
act as an interface. Call it "InterfaceDll".

Here is the code for the source file in this project. Compile it.

using System;
namespace InterfaceDll
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public abstract class TheInterface
{
public abstract int DoSomething1();
public abstract int DoSomething2();
}
}

2. Create another "Class library" project. Call it "ImplementationDll".
Add a project reference to the built "InterfaceDll" you created in step one.
Here is the source for this one.

using System;
namespace ImplementationDll
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Implementation : InterfaceDll.TheInterface
{
public Implementation()
{
}
public override int DoSomething1()
{
//byte[] myBytes = {0xFF, 0xFF, 0xFF, 0xFF};
//foreach (byte b in myBytes)
//{
// Console.Write(b.ToString() );
//}
return 0;
}
public override int DoSomething2()
{
return 0;
}
}
}

* Note the lines commented out. Leave them commented out for now. Build
this dll.

3. Create a Windows forms app with a single button on the form. Add a
reference to the "InterfaceDll.dll" built in step 1 to this project. Add a
click handler for the button. Add the following code to the button handler.

string strCurDir = Environment.CurrentDirectory;
string filename = Path.Combine(strCurDir, "implementationdll.dll" );
//Load the Assembly
Assembly a = Assembly.LoadFrom(filename);
// get all the types in the loaded assembly
Type[] types = a.GetTypes();
foreach (Type typ in types)
{
// dynamically create or activate(if exist) object
object obj = Activator.CreateInstance(typ);
}

Build the forms app. Now, copy the "ImplementationDll.dll" from step 2 into
the "\bin\Debug" directory so the code can locate the assembly.

4. Run the windows forms app. Click the button. Note how it runs
properly.

5. Now, uncomment the code in the "DoSomething1" method in the
"ImplementationDll" project, build it and (DON'T FORGET) copy the new dll
into the same location as in step 3.

6. Run the windows forms app again. Click the button. It will throw an
exception on the "object obj = Activator.CreateInstance(typ);" line.

"An unhandled exception of type 'System.MissingMethodException'
occurred in mscorlib.dll
Additional information: No parameterless constructor defined for
this object."

If you change the byte[] array allocation to use "new" instead of an
initializer list like the following, it works ok.

byte[] myBytes = new byte[4];
myBytes[0] = myBytes[1] = myBytes[2] = myBytes[3] = 0xFF;

Why does using an initializer for the byte[] array in the "DoSomething1"
method cause an error? Am I doing something wrong?

Thanks!

Terry

"Jon Skeet" <sk***@pobox.com> wrote in message
news:MP************************@news.microsoft.com ...
Terry <ch**********@hotmail.com> wrote:
I'm a bit puzzled by this. How can all function local code affect the
creation of an object? And why would it make a difference how the array is created and initialized within a method of the derived class?

Can anyone help clear this up? Am I doing something I shouldn't be?


<snip>

That sounds very odd to me. Could you provide a short but complete
example which demonstrates the problem?
See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #3
Terry <ch**********@hotmail.com> wrote:
Ok. Here it is. Here's a simple test case which demonstrates the problem
I'm having. If I'm doing something wrong, please let me know.


<snip>

Brief request - I reckon it's generally easier to do this kind of thing
with console apps. In fact, you don't even need the three different
classes here. Here's a short class which demonstrates everything:

using System;
using System.Reflection;

class Test
{
public static void Main()
{
try
{
foreach (Type t in
Assembly.GetExecutingAssembly().GetTypes())
{
Console.WriteLine (t.Name);
Activator.CreateInstance (t);
}
}
catch (Exception e)
{
Console.WriteLine (e);
}
}

public void Foo()
{
byte[] myBytes = {0xFF, 0xFF, 0xFF, 0xFF};
}
}
Even with the three-class system a console app would end up being
shorter to demonstrate with. Anyway, on with the problem itself.
You're iterating over *all* the types within the assembly - and the one
which is failing (at least on my system) is a type called:
<PrivateImplementationDetails> (including the angle brackets).

If you compile the console app above and run it, you'll see the same
thing. Comment out the line in Foo and it runs fine. Comment out the
line using Activator.CreateInstance instead, and you'll get something
like:

Test
<PrivateImplementationDetails>
$$struct0x6000002-1

Now, using Reflector (http://www.aisto.com/roeder/dotnet/) or ildasm
you can have a look and see that the struct is nested within
<PrivateImplementationDetails>. I believe it basically contains the
initialisation data for the byte array. Add some more arrays and you'll
see the same thing, growing and growing. Look at mscorlib and there are
loads of them.

The upshot of this is that you should basically take more care about
which types you want to create instances of, although I agree it's a
somewhat surprising case. If you only look at public types (using
Type.IsPublic) you should be fine.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #4
Ah. I see. Thank you very much! You're a credit to the Internet! :-)

Terry

"Jon Skeet" <sk***@pobox.com> wrote in message
news:MP************************@news.microsoft.com ...
Terry <ch**********@hotmail.com> wrote:
Ok. Here it is. Here's a simple test case which demonstrates the problem I'm having. If I'm doing something wrong, please let me know.


<snip>

Brief request - I reckon it's generally easier to do this kind of thing
with console apps. In fact, you don't even need the three different
classes here. Here's a short class which demonstrates everything:

using System;
using System.Reflection;

class Test
{
public static void Main()
{
try
{
foreach (Type t in
Assembly.GetExecutingAssembly().GetTypes())
{
Console.WriteLine (t.Name);
Activator.CreateInstance (t);
}
}
catch (Exception e)
{
Console.WriteLine (e);
}
}

public void Foo()
{
byte[] myBytes = {0xFF, 0xFF, 0xFF, 0xFF};
}
}
Even with the three-class system a console app would end up being
shorter to demonstrate with. Anyway, on with the problem itself.
You're iterating over *all* the types within the assembly - and the one
which is failing (at least on my system) is a type called:
<PrivateImplementationDetails> (including the angle brackets).

If you compile the console app above and run it, you'll see the same
thing. Comment out the line in Foo and it runs fine. Comment out the
line using Activator.CreateInstance instead, and you'll get something
like:

Test
<PrivateImplementationDetails>
$$struct0x6000002-1

Now, using Reflector (http://www.aisto.com/roeder/dotnet/) or ildasm
you can have a look and see that the struct is nested within
<PrivateImplementationDetails>. I believe it basically contains the
initialisation data for the byte array. Add some more arrays and you'll
see the same thing, growing and growing. Look at mscorlib and there are
loads of them.

The upshot of this is that you should basically take more care about
which types you want to create instances of, although I agree it's a
somewhat surprising case. If you only look at public types (using
Type.IsPublic) you should be fine.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: ka | last post by:
I'm implementing an IDesignerHost, for the CreateComponent method. The code below is quite standard. When loading a form, the CreateComponent works fine. However, when someone choose a control from...
7
by: hazz | last post by:
this is a repost with more concise code (well, for me) and better questions (I hope....) . given the following two classes, my intent is to use either Activator.CreateInstance or InvokeMember pass...
4
by: Martin Maat | last post by:
Hi. I am using a COM component from managed code doing the following: Type type = Type.GetTypeFromCLSID(new Guid("B70FAAE6-4F85-480A-B1C5-DC9A6F175BFC"), serverMachineName, true); history =...
4
by: garak | last post by:
Hi, I got the following problem : I have an defined an Array of different Actions: public PRootActions AllActions = new PRootActions ; I got a dynamic method where all Actions or other...
2
by: Frank Pleyer via .NET 247 | last post by:
Hi, I got the following problem : I have an defined an Array of different Actions: public PRootActions AllActions = new PRootActions ; I got a dynamic method where all Actions or other...
3
by: Doug Riley | last post by:
I am using CreateInstance to create an instance of a class and invoke a function of that class. I really need it to execute in a single line of code (long story, but I want to execute this code in...
6
by: CreateObject | last post by:
Assume that I have the classes below; class mercedes: IAuto { .... } class ford: IAuto{ .... }
1
by: learning | last post by:
Hi how can I instaltiate a class and call its method. the class has non default constructor. all examples i see only with class of defatul constructor. I am trying to pull the unit test out from...
11
by: Matthew Wells | last post by:
Hello. I have figured out how to create an instance of an object only knowing the type by string. string sName = "MyClassName"; Type t = Type.GetType(sName); Object objNew =...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.