CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Sep 2011
    Posts
    3

    Generics conversion problem

    I've got an conversion issue with converting an instance to a certain class. This instance is created after I scanned my assembly for a certain type. Don't ask why I'm doing this in complex way. I've got a very good reason for it. Trust me .

    I've place three conversions in the code. The third one isn't working but should be correct. Does anybody knows a trick to get the third conversion working too.

    Tnx.


    @@csharp
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    namespace ReflectionTest2
    {
    class Program
    {
    static void Main(string[] args)
    {
    Assembly assembly = Assembly.GetExecutingAssembly();

    // Get all types which implement IElementUpdater
    List<Type> typeToChecks = assembly.GetTypes().Where
    (t => ((typeof(IElementUpdater).IsAssignableFrom(t)
    && t.IsClass && !t.IsAbstract))).ToList();

    foreach (Type typeToCheck in typeToChecks)
    {
    var instance = MyObjectFactory.CreateObject(typeToCheck);

    // Conversion works fine but I'm not able to call the Foo method
    IElementUpdater one = instance as IElementUpdater;

    // Conversion works fine but is only to proof it is of the correct type
    SaleElementUpdateHandler two = instance as SaleElementUpdateHandler;

    // Conversie doesn't work
    IElementUpdater<IBaseTransactionElement> three = instance as IElementUpdater<IBaseTransactionElement>;
    }
    }
    }

    public interface IBaseTransactionElement
    {
    }

    public interface IElementUpdater
    {
    }

    public interface IElementUpdater<T> : IElementUpdater where T : IBaseTransactionElement
    {
    void Foo(T element);
    }

    public class SaleElementUpdateHandler : IElementUpdater<FooBar>
    {
    #region IElementUpdater<FooBar> Members

    public void Foo(FooBar element)
    {
    throw new NotImplementedException();
    }

    #endregion
    }

    public class FooBar : IBaseTransactionElement
    {
    }
    }
    @@

  2. #2
    Join Date
    Mar 2004
    Location
    Prague, Czech Republic, EU
    Posts
    1,701

    Re: Generics conversion problem

    It is because generics in C# don't support covariance and contravariance (althought CLR does). You can cast the instance to IElementUpdater<FooBar>, but not to IElementUpdater<IBaseTransactionElement>, despite that FooBar implements IBaseTransactionElement.
    • Make it run.
    • Make it right.
    • Make it fast.

    Don't hesitate to rate my post.

  3. #3
    Join Date
    Sep 2011
    Posts
    3

    Re: Generics conversion problem

    Thanks for your reply and answer. I understand why it doesn't work. Could it be made possible by implementing iconvertible or something similar?

    Tnx for your effort.

  4. #4
    Join Date
    Mar 2004
    Location
    Prague, Czech Republic, EU
    Posts
    1,701

    Re: Generics conversion problem

    There is a solution, or better workaround, which is explicit interface implementation.
    Code:
    public class SaleElementUpdateHandler : IElementUpdater<FooBar>, IElementUpdater<IBaseTransactionElement>
      {
        #region IElementUpdater<FooBar> Members
    
        public void Foo(FooBar element)
        {
          throw new NotImplementedException();
        }
    
        #endregion
    
        #region IElementUpdater<IBaseTransactionElement> Members
    
        void IElementUpdater<IBaseTransactionElement>.Foo(IBaseTransactionElement element)
        {
          throw new NotImplementedException();
        }    
        #endregion
      }
    • Make it run.
    • Make it right.
    • Make it fast.

    Don't hesitate to rate my post.

  5. #5
    Join Date
    Sep 2011
    Posts
    3

    Re: Generics conversion problem

    Hmmmm....I'm sorry but I don't find this a real solution.

    The nice thing about generics is that my Foo method will always receive a strong typed object. No conversion is needed. With the extra method I'll always have to a cast which can anything if it a IBaseTransactionElement.

    public void Foo(IBaseTransactionElement element)
    {
    this.Foo(element as FooBar);
    }

    I've already solved my problem with reflection. My provider class will load all classes of type IElementUpdater<T> and stores the methodinfo of the interface itself.

    MethodInfo mi = typeToCheck.GetMethod("Foo");

    After that it's just a matter of invoking the MethodInfo. I've been told invoking is slighty slower but I don't think it will matter in our case.

    Cheers.

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Generics conversion problem

    Quote Originally Posted by KiwiDre View Post
    I've been told invoking is slighty slower but I don't think it will matter in our case.
    Reflection and invoking is way slower. It pretty much should be used as a last resort.

  7. #7
    Join Date
    Sep 2011
    Posts
    3

    Re: Generics conversion problem

    Way slower?? How much slower?? Do you have any info about the performance loss?

    The reflection part is done once and that's it. I'll do a test to see how much slower the invoke is.

    !!!UPDATE!!!
    SMALL TEST COMPLETED

    And the results are:
    Function call direct duration (#Iterations: 100000)
    Elapsed time: 00:00:00.0006791
    Elapsed milliseconds: 0
    Elapsed ticks: 2039

    Function call invoke duration (#Iterations: 100000)
    Elapsed time: 00:00:00.0977379
    Elapsed milliseconds: 97
    Elapsed ticks: 293439

    This is much more than I anticipated. Nevertheless, I don't think it will be a bottleneck for us. And if it is we might start use Boudino's approach.
    Last edited by KiwiDre; September 20th, 2011 at 04:51 PM.

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Generics conversion problem

    Search bing or google for "reflection performance".

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured