Taher
Taher

Reputation: 593

Overload extension method for multiple classes

In my project I have a class that represents a certain document type. Each class has its own properties and methods although there are some similarities between them.

I am trying to implement an extension method for each class that has the same name (method overloading) but I am getting an ambiguous call error

Code to explain further

Document Type A class representation:

static class DocType_A
{
    private static XElement baseDocType_A = XmlFiles[0].Root;

    // Extension Method
    internal static IEnumerable<ViewData> AsViewData(this IEnumerable<XElement> result)
    {
        return
            from doc in result select new ViewData { };
    }


    // Contains methods for querying through the XML file of this [DocType_A] type
    internal static class Query
    {
        internal static IEnumerable<XElement> ByStatusOrAny(byte status = 0)
        {
            return baseDocType_A.Descendants("DocType_A").Select(doc => doc);
        }

        internal static IEnumerable<XElement> Expired()
        {
            return baseDocType_A.Descendants("DocType_A").Where("some conditions").Select(doc => doc);
        }

    }

    // Represents the data needed to be displayed to the user via the DGV
    internal class ViewData
    {
        // [DocType_A] related Property 
    }

    internal class Counter
    {
        // some property
    }

}

Document Type B class representation:

static class DocType_B
{
    private static XElement baseDocType_B = XmlFiles[1].Root;

    // Extension Method
    internal static IEnumerable<ViewData> AsViewData(this IEnumerable<XElement> result)
    {
        return
            from doc in result select new ViewData { };
    }


    // Contains methods for querying through the XML file of this [DocType_A] type
    internal static class Query
    {
        internal static IEnumerable<XElement> ByStatusOrAny(byte status = 0)
        {
            return baseDocType_B.Descendants("DocType_B").Select(doc => doc);
        }

        internal static IEnumerable<XElement> Expired()
        {
            return baseDocType_B.Descendants("DocType_B").Where("some conditions").Select(doc => doc);
        }

    }

    // Represents the data needed to be displayed to the user via the DGV
    internal class ViewData
    {
        // [DocType_B] related Property 
    }

    internal class Counter
    {
        // some property
    }
}

Usage:

class SomeApplicationClass
{
    void Method()
    {
        IEnumerable<DocType_A.ViewData> query = DocType_A.Query.ByStatusOrAny().AsViewData();
    }

    void SomeOtherMethod()
    {
        IEnumerable<DocType_B.ViewData> query = DocType_B.Query.ByStatusOrAny().AsViewData();
    }
}

But I am getting ambiguous call error.

Is is possible to make extension method for each class with the same name?

error

Upvotes: 0

Views: 727

Answers (3)

Neil.Work
Neil.Work

Reputation: 1025

The extension methods that you are creating aren't for Doctype_A or Doctype_B, you are creating them for the IEnumerable < XElement >. So you do actually have two extension methods with the same signature.

If you want one specific to A or B, you'd do it like this

    internal static IEnumerable<XElement> ByStatusOrAny(this DocType_A doc, byte status = 0)
    {
        return doc.Query.Descendants("DocType_A").Select(doc => doc);
    }

and then call it like

    DocType_A.ByStatusOrAny().AsViewData();

I know you want it to be scoped, but that's not how it works. Whatever has the [this] qualifier is what the extension method is going to be applied to, regardless of the class it's in. You might be able to do what you want if you keep each extension method in a different namespace and only reference the namespace you want in the specific files you want, but I've never tried that, so your mileage may very.

Also, as others have pointed out, your example doesn't seem to fit the normal use case for extension methods. So if that's really what you are doing you might want to rework something.

Upvotes: 2

golobitch
golobitch

Reputation: 1334

I believe that your problem is here:

internal static IEnumerable<ViewData> AsViewData(this IEnumerable<XElement> result)

You have one metod like this in DocType_B and DocType_A ... if you remove static, it should work, but I don't think this is a way to go.

Upvotes: 0

Christopher
Christopher

Reputation: 9804

You are thinking about extension Methods as if they were class Methods. They are not.

What they actually are is syntax sugar for a bunch of static Methods, so the compiler & Intellisense can help you calling them.

You have to functions that require a parameter of type IEnumerable<XElement>. Wich one is the compiler suppsoed to call on a IEnumerable<XElement>? For all intents of overload checking, the "this" parameters is ignored. After after that you have two functions with the same name and with any parameter types to differentiate on.

Upvotes: 0

Related Questions