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.
精彩评论