views:

98

answers:

2

Why I'm unable to extend an abstract class. Is there any work around to achieve this?

In silverlight, Enum.GetNames is missing. So, I would like to extend it and have it in my utility assembly. By then, got into this.

+3  A: 

The problem here is not that you can't add an extension method to an abstract class (you can - you can add an extension method to any type) - it's that you can't add a static method to a type with extension methods.

Extension methods are static methods that present themselves in C# as instance methods. But they're still static. Adding a static method to a type requires the ability to redefine the type, which you can only do if you have the source code :)

Best bet, if you want this method, is to write your own static and see if you can perhaps rip the code out of reflector.

However, it's entirely possible that it's not there because it's physically not supported in Silverlight (I don't know - I haven't investigate)

EDIT

Following on from your comment - and I hope that I've understood you here - I think what you want to be able to do is something like this (targetting object to prove the point):

public static class ExtraObjectStatics
{
  public static void NewStaticMethod()
  {

  }
}

public class Test
{
  public void foo()
  {
    //You can't do this - the static method doesn't reside in the type 'object'
    object.NewStaticMethod();
    //You can, of course, do this
    ExtraObjectStatics.NewStaticMethod();
  }
}

If you think about it - of course you can't inject new static methods into an existing type because, like I said in paragraph two, you have to be able to recompile the underlying type; and there simply is no way around that.

What you can do is (and I don't actually recommend this - but it's an option) create yourself a new type called Enum and place it inside a new namespace:

namespace MySystem
{
  public class Enum
  {
    public static string[] GetNames()
    {
      //don't actually know how you're going to implement it :)
    }
  }
}

And now - when you want to use it, what you can't do is this:

using System;
using MySystem;

namespace MyCode
{
  public class TestClass
  {
    public static void Test()
    {
      Enum.GetNames(); //error: ambiguous between System and MySystem
    }
  }
}

Because the using in the outermost scope to both 'System' and 'MySystem' will cause the compiler not to be able to resolve the correct Enum type.

What you can do, however, is this:

using System;

namespace MyCode
{
  using MySystem; //move using to inside the namespace
  public class TestClass
  {
    public static void Test()
    {
      //will now work, and will target the 'MySystem.Enum.GetNames()'
      //method.
      Enum.GetNames();
    }
  }
}

Now, code within that namespace (within that file only) will always resolve Enum to the one in your namespace because that's the nearest using directive in terms of scope.

So, you can think of this as overriding the whole Enum type for the benefit of a given namespace that includes a using MySystem; in it.

But, it does exactly that - it replaces the existing System.Enum with MySystem.Enum - meaning that you lose all the members of the System.Enum type.

You could get around this by writing wrapper methods in your Enum type around the System.Enum versions - making sure that you fully-qualify the type as System.Enum.

Having looked at the implementation of the GetNames method in Reflector - it relies on internal data that I don't think you're going to be able to build... but I would be very interested to hear if you are actually able to reproduce the method in Silverlight.

Andras Zoltan
Exactly, you are right! I was wrong complaining about abstract class. I Apologize. I tested it, worked. But, What I exactly want is; Since, the methods in extension are static in nature why they are not accessible for me. Any clue or work around would be great full!
Avatar
I'm not entirely sure what you mean by this. If you have `public static class ObjectExtensions { public void ExtMethod(this object o) { } }` then you can directly reference that `ExtMethod` using the qualified name `ObjectExtensions.ExtMethod(MyObject)` if you want to. But you won't be able to get it to appear as `object.ExtMethod` because `ExtMethod` doesn't belong to the `object` type - it belongs to `ObjectExtensions`.
Andras Zoltan
To put it another way - you can only extend an instance of a type with static methods (via extension methods). If you want to add a new static method to an existing type; you can't without rewriting the underlying type (or using implicit static inheritance, which isn't suitable in this case). If that type is therefore inside the CLR, you'll have to resort to a new static method in another type.
Andras Zoltan
@Avatar - have updated my answer with an idea that might be of use. fundamentally though it's still the case that you can't add a new static method to another type without recompiling it (I know I've said that about 4 times now, sorry!)
Andras Zoltan
Thanks a lot Andras Zoltan for your effort. Finally, I end of something like follows. Enum<GroupAlignment>.GetNames();Thanks once again :)PS: GroupAlignment is my enum.
Avatar
@Avatar - good solution; happy to be of help
Andras Zoltan
+2  A: 
public abstract class Foo
{
  public abstract void Bar();
}

public static class FooExtensions
{
  // most useless extension method evar
  public static void CallBar(this Foo me)
  {
    me.Bar();
  }
}

Sure, no problem.

Will
+1 Thanks It worked. But, doesn't solve my problem.
Avatar
that is an awesome extension method - can I put it into our core libraries?
Andras Zoltan