Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / July 2006

Tip: Looking for answers? Try searching our database.

Building an array type by Reflection.Emit

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Edgile - 20 Jul 2006 14:27 GMT
The aim of my app is to auto-generate classes by System.Reflection.Emit.
Let's say that the targeted auto generated class should look like this:

public class MyClass
{
  public static MyClass   GetInstance(string id)
  {
  ...
  }
  public static MyClass[] GetInstances()
  {
  ...
  }
}

Now, does anybody know, how to get the type of MyClass[] programmatically in
the place of the question marks below?
The code that generates the fragment above would look like this:

using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

AssemblyBuilder aB  = Thread.GetDomain().DefineDynamicAssembly(...);
ModuleBuilder mB    = aB.DefineDynamicModule(...);
TypeBuilder myClass = mB.DefineType("MyClass", TypeAttribute.Public |
TypeAttribute.Class, null);

// Creating method MyClass GetInstance(string id) MethodBuilder getInstance
= myClass.DefineMethod("GetInstance",
MethodAttributes.Public | MethodAttributes.Static, myClass, new
Type[]{typeof(string)}); ILGenerator ilg = getInstance.GetILGenerator();
ilg.Emit(...);

// Creating method MyClass[] GetInstances() Type myClassArray = ????????; //
WHAT SHOULD COME HERE?
MethodBuilder getIntances = myClass.DefineMethod("GetInstances",
MethodAttributes.Public | MethodAttributes.Static, myClassArray, new
Type[]{}); ilg = getInstance.GetILGenerator(); ilg.Emit(...);

myClass.CreateType();

 
Please mind, that the sheer purpose of this code generation is to provide
design-time type safety. Therefore alternatives like returning object[]
instead of MyClass[] are not a solution. Any help is appreciated.
Barry Kelly - 20 Jul 2006 15:31 GMT
> public class MyClass
> public static MyClass[] GetInstances()

> Now, does anybody know, how to get the type of MyClass[] programmatically in
> the place of the question marks below?

You do it with Type.MakeArrayType().

> TypeBuilder myClass

> // Creating method MyClass[] GetInstances() Type myClassArray = ????????; //
> WHAT SHOULD COME HERE?
> MethodBuilder getIntances = myClass.DefineMethod("GetInstances",
> MethodAttributes.Public | MethodAttributes.Static,

 myClass.MakeArrayType(),

> new Type[]{});

-- Barry

Signature

http://barrkel.blogspot.com/

Edgile - 20 Jul 2006 21:59 GMT
Thanx for the quick response. Almost good. The "MakeArrayType" method is
available only in .NET2.0, but a solution would be needed for v1.1. Any other
ideas?

> You do it with Type.MakeArrayType().
Barry Kelly - 20 Jul 2006 23:40 GMT
> Thanx for the quick response. Almost good. The "MakeArrayType" method is
> available only in .NET2.0, but a solution would be needed for v1.1. Any other
> ideas?

The only other way I know to create that guy is to use
Array.CreateInstance and get the type of the return value, which would
be quite an awkward workaround.

-- Barry

Signature

http://barrkel.blogspot.com/

Ben Voigt - 21 Jul 2006 00:27 GMT
> Thanx for the quick response. Almost good. The "MakeArrayType" method is
> available only in .NET2.0, but a solution would be needed for v1.1. Any
> other
> ideas?

ModuleBuilder.GetType seems to be promising.... it handles [], *, & for
arrays, pointers and references.  If any of those are present, it ends up
calling:
private Type GetType(string strFormat, Type baseType)
{
     if ((strFormat == null) || strFormat.Equals(string.Empty))
     {
           return baseType;
     }
     char[] chArray1 = strFormat.ToCharArray();
     return SymbolType.FormCompoundType(chArray1, baseType, 0);
}

And FormCompoundType looks like just what you ordered.  In fact, you might
be able to get away with directly calling this overload of GetType via
reflection, but myDynamicModule.GetType(myTypeBuilder.FullName + "[]") looks
like the approved way.

Of course, you can use another MSIL-creation tool, such as Phoenix
(http://research.microsoft.com/phoenix/) which gives you complete control.

>> You do it with Type.MakeArrayType().
Barry Kelly - 21 Jul 2006 01:03 GMT
> > Thanx for the quick response. Almost good. The "MakeArrayType" method is
> > available only in .NET2.0, but a solution would be needed for v1.1. Any
[quoted text clipped - 3 lines]
> ModuleBuilder.GetType seems to be promising.... it handles [], *, & for
> arrays, pointers and references.

It would be cool if that works. I note that the .NET 2 docs have this
stern warning in the Remarks section:

"Do not use this method to generate array types, pointer types, or byref
types. Use the TypeBuilder.MakeArrayType, TypeBuilder.MakePointerType,
and TypeBuilder.MakeByRefType methods instead."

... but that only really makes sense if those methods exist before 2.0.

-- Barry

Signature

http://barrkel.blogspot.com/

Edgile - 21 Jul 2006 08:12 GMT
> but myDynamicModule.GetType(myTypeBuilder.FullName + "[]") looks
> like the approved way.

Hello guys,

Thanx for this fascinating fast response time. This proposal works fine, I
am happy!

"Barry Kelly" wrote:
> Array.CreateInstance and get the type of the return value, which would
> be quite an awkward workaround.

Yes, it is awkward but I tried it before I submitted my trouble here. It
does not work. After I tried, I recognized that it obviously cannot work as
creating an instance of a type under construction is far from a good solution
:)

Thanks again for you kindness and help!
Barry Kelly - 21 Jul 2006 08:44 GMT
> Yes, it is awkward but I tried it before I submitted my trouble here. It
> does not work. After I tried, I recognized that it obviously cannot work as
> creating an instance of a type under construction is far from a good solution

Yes, you'd need to create the whole module before you create the type. A
third way is to output IL instead, and call ILASM. But, it's great you
found a solution!

-- Barry

Signature

http://barrkel.blogspot.com/

Ben Voigt - 21 Jul 2006 15:09 GMT
>> Yes, it is awkward but I tried it before I submitted my trouble here. It
>> does not work. After I tried, I recognized that it obviously cannot work
[quoted text clipped - 5 lines]
> third way is to output IL instead, and call ILASM. But, it's great you
> found a solution!

But the array was supposed to be a static member of the type itself.... I do
that a fair amount myself actually, though not through Reflection.Emit.
Thankfully, I get to use .Net 2.0 exclusively now as well.  But Reflector's
search for methods containing the word array, sorted by namespace, plus a
little browsing around, came up with the answer pretty quickly.

> -- Barry
Barry Kelly - 21 Jul 2006 15:23 GMT
> But the array was supposed to be a static member of the type itself....

I know!

> I do
> that a fair amount myself actually, though not through Reflection.Emit.
> Thankfully, I get to use .Net 2.0 exclusively now as well.

I managed to get .Net 2.0 adopted when it first came out CTPs and early
beta, so I never had to deal with these issues in my own codegen :)

-- Barry

Signature

http://barrkel.blogspot.com/


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.