开发者

c# polymorphism without method overloading (for a webmethod)

开发者 https://www.devze.com 2023-04-11 23:18 出处:网络
Okay, so I realised after writing some overloaded methods that webmethods can\'t be overloaded (by realised I mean VSthrew a paddy and wouldn\'t allow me to update the service references). I have trie

Okay, so I realised after writing some overloaded methods that webmethods can't be overloaded (by realised I mean VS threw a paddy and wouldn't allow me to update the service references). I have tried to get around that like this:

    开发者_如何学编程public string DoPing<T>(T IP)
    {

        if (typeof(T) == typeof(string))
        { 
            return DoPingString(IP);
        }
        if (typeof(T) == typeof(IPAddress))
        {
            return DoPingIP(IP);
        }
        throw new Exception("Programmer Error");
    }

But I'm getting a cannot convert from T to string/Ipadress error when I call the respective (renamed) methods. Can someone explain why it doesn't work, and possibly either fix it or give me an alternate solution? Thanks in advance.

Edit: Good point, generics are probably overkill (I tried for another solution and failed before trying this). DoPingString(string String) and DoPingIP(IPAdress Address) are the signatures. I will give the tick to the closest answer tomorrow. I solved the problem in a separate way.


You can use WebMethodAttribute :

[WebMethod(MessageName = "DoPingIPAddress")]
public string DoPing(IPAddress ip) { }

[WebMethod(MessageName = "DoPingString")]
public string DoPing(string ip) { }

But from the client side, you'll have two different methods : it's web services/SOAP constraints.

Documentation


You're not using generics the way it was intended. The compiler has no idea what type T is, so it won't just let you implicitly or explicitly cast to String or IPAddress. Here's a version that works:

    public string DoPing<T>(T IP)
    {
        if (typeof(T) == typeof(string))
        {
            return DoPingString((String)Convert.ChangeType(IP, typeof(String)));
        }
        if (typeof(T) == typeof(IPAddress))
        {
            return DoPingIP((IPAddress)Convert.ChangeType(IP, typeof(IPAddress)));
        }
        throw new Exception("Programmer Error");
    }

However, since you're using generics with no constraint, you gain no benefit from the generic implementation. Why not just take an object?

public string DoPing(Object IP)
{
    if (IP.GetType() == typeof(string))
    {
        return DoPingString((String)IP);
    }
    if (IP.GetType() == typeof(IPAddress))
    {
        return DoPingIP((IPAddress)IP);
    }
    throw new Exception("Programmer Error");
}

Of course, the simpler and easier approach would be to simply overload your function, i.e.:

public string DoPing(string IP)
{
    return DoPingString(IP);
}
public string DoPing(IPAddress IP)
{
    return DoPingIP(IP);
}


Try using Convert.ChangeType method then cast as usual:

if (typeof(T) == typeof(string))
{ 
    return DoPingString((string)Convert.ChangeType(IP, typeof(string)));
}
if (typeof(T) == typeof(IPAddress))
{
   return DoPingIP((IPAddress)Convert.ChangeType(IP, typeof(IPAddress)));
}


It sounds like you want the KnownTypeAttribute available in WCF. But seeing as you can't use that here and you definitely want only one method then I think the only way is to just offer two parameters. Just add some validation to check for nulls and pass them on to your private helper methods.

[WebMethod] 
public string DoPing(string ipString, IPAddress ipAdress)
{
    if(ipString != null)
    {
        DoPing(ipString);
    }
    if(ipAdress != null)
    {
        DoPing(ipAdress);
    }
}


I would better do this:

public string DoPing(IPAddress ip)
{
    ...logic...
}

public string DoPing(String ip)
{
    ...logic...
}

Try to avoid unnecessary patterns and templates.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号