Article View: borland.public.csharpbuilder.language.csharp
Article #143Re: More about "class of" in C#
From: David Fallas
Date: Fri, 22 Jun 2007 01:02
Date: Fri, 22 Jun 2007 01:02
152 lines
5252 bytes
5252 bytes
For the sake of completeness for anyone referring to this thread in future -
there is a little bit more to the story if using the first strategy
suggested.
Where there is a requirement to call a static method which has NOT been
overridden in a descendent class, the type.GetMethod() method will not find
it (where type is the descendent's type).
Instead, if it isn't known if the method has been overridden or not, one
needs to check the return from the type.GetMethod("xxxx") call and if null,
call type.BaseType.GetMethod("xxxx") to find the base class' implementation
of the method.
This appears to differ significantly from Delphi which seems to be capable
of finding either a base or overridden method quite happily.
"Joanna Carter [TeamB]" <joanna@nospam.for.me> wrote in message
news:4677b67f@newsgroups.borland.com...
> Borland a οΏ½crit :
>
>> Referring to that posting from December last year re "class of"... I
>> understand the use of Activator.CreateInstance(ClassType) as a
>> replacement for the Delphi "class of" for use in a C# abstract class
>> factory, but how would I use that ClassType reference to call a static
>> method (eg public static DoIt()) which has been declared in the Class
>> class?
>>
>> In Delphi I would simply retrieve the "class of" reference, (eg
>> ClassClass - class of TClass), and call the function normally - eg
>> TClass(ClassClass).DoIt;
>
> First, can I ask you to change your posting name from Borland ?
>
> Now, to the matter in hand.
>
> Don't forget that, in C#, static methods cannot be virtual. Therefore, you
> have to redlclare the method in each and every derived class but simply
> calling the static method on the base type will only call that method, not
> the derived one.
>
> However, here is a simple example fo how to create a factory class that
> will call the correct method, depending on the type passed in.
>
> public class Base
> {
> public static void DoIt(int arg) { }
> }
>
> public class Derived : Base
> {
> public static void DoIt(int arg) { }
> }
>
> public static class Factory
> {
> public static void DoIt(Type type, int arg)
> {
> if (!typeof(Base).IsAssignableFrom(type))
> throw new Exception("Type must derive from Base");
>
> Type[] argTypes = new Type[] { typeof(int) };
>
> MethodInfo mi = type.GetMethod("DoIt", argTypes);
>
> object[] args = new object[] { arg };
>
> mi.Invoke(null, args);
> }
> }
>
> private void button1_Click(object sender, EventArgs e)
> {
> Type type = typeof(Derived);
>
> Factory.DoIt(type, 123);
> }
>
> You can also use the idea of a metaclass to achieve a more Delphi-like
> syntax.
>
> public class Base
> {
> #region metaclass
>
> public class ClassReference
> {
> #region private members
>
> private Type internalType;
>
> #endregion
>
> public void DoIt(int value)
> {
> MethodInfo methodInfo = internalType.GetMethod("DoIt",
> BindingFlags.Public | BindingFlags.Static);
>
> object[] args = new object[] { value };
>
> methodInfo.Invoke(null, args);
> }
>
> #endregion
>
> #region constructors
>
> // default constructor
> private ClassReference(Type type)
> {
> internalType = type;
> }
>
> #endregion
>
> #region implicit conversion operator
>
> public static implicit operator ClassReference(Type input)
> {
> if (!typeof(Shape).IsAssignableFrom(input))
> throw new ArgumentException(String.Format("Type {0} must derive
> from {1}", input.Name, typeof(Base).Name), "input");
>
> return new ClassReference(input);
> }
>
> #endregion
> }
>
> #endregion
>
> public static void DoIt(int value) {...}
> }
>
> public class Derived : Base
> {
> public static void DoIt() {...}
> }
>
> This then allows the following calling syntax :
>
> {
> Base.ClassReference classRef = typeof(Derived);
>
> classRef.DoIt(123);
> }
>
> Is that what you are looking for ?
>
> Joanna
>
> --
> Joanna Carter [TeamB]
> Consultant Software Engineer
Technical Details
Message-ID:
<467b1fbe$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!news1.google.com!news.glorb.com!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mailReferences:
<467757d6$1@newsgroups.borland.com> <4677b67f@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 1efe35,77a80b77cf3a9a3e X-Google-Attributes: gid1efe35,public,usenet X-Google-Language: ENGLISH,ASCII From: "David Fallas" <fallasd@sysmex.co.nz> Newsgroups: borland.public.csharpbuilder.language.csharp References: <467757d6$1@newsgroups.borland.com> <4677b67f@newsgroups.borland.com> Subject: Re: More about "class of" in C# Date: Fri, 22 Jun 2007 13:02:40 +1200 Lines: 154 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.2869 X-RFC2646: Format=Flowed; Response X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962 NNTP-Posting-Host: 210.55.97.206 Message-ID: <467b1fbe$1@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1182474174 210.55.97.206 (21 Jun 2007 18:02:54 -0700) Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!news1.google.com!news.glorb.com!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail