Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, March 12, 2016

Cast object to T

Cast object to T


I'm parsing an XML file with the XmlReader class in .NET and I thought it would be smart to write a generic parse function to read different attributes generically. I came up with the following function:

private static T ReadData(XmlReader reader, string value)  {      reader.MoveToAttribute(value);      object readData = reader.ReadContentAsObject();      return (T)readData;  }  

As I came to realise, this does not work entirely as I have planned; it throws an error with primitive types such as int or double, since a cast cannot convert from a string to a numeric type. Is there any way for my function to prevail in modified form?

Answer by Bob for Cast object to T


First check to see if it can be cast.

if (readData is T) {      return (T)readData;  } else {      try {         return (T)Convert.ChangeType(readData, typeof(T));      } catch (InvalidCastException) {         return default(T);      }  }  

Answer by Lasse V. Karlsen for Cast object to T


Have you tried Convert.ChangeType?

If the method always returns a string, which I find odd, but that's besides the point, then perhaps this changed code would do what you want:

private static T ReadData(XmlReader reader, string value)  {      reader.MoveToAttribute(value);      object readData = reader.ReadContentAsObject();      return (T)Convert.ChangeType(readData, typeof(T));  }  

Answer by Ricardo Villamil for Cast object to T


Add a 'class' constraint (or more detailed, like a base class or interface of your exepected T objects):

private static T ReadData(XmlReader reader, string value) where T : class  {      reader.MoveToAttribute(value);      object readData = reader.ReadContentAsObject();      return (T)readData;  }  

or where T : IMyInterface or where T : new(), etc

Answer by ChrisW for Cast object to T


You can presumably pass-in, as a parameter, a delegate which will convert from string to T.

Answer by Tom Ritter for Cast object to T


You could require the type to be a reference type :

 private static T ReadData(XmlReader reader, string value) where T : class   {       reader.MoveToAttribute(value);       object readData = reader.ReadContentAsObject();       return (T)readData;   }  

And then do another that uses value types and TryParse...

 private static T ReadDataV(XmlReader reader, string value) where T : struct   {       reader.MoveToAttribute(value);       object readData = reader.ReadContentAsObject();       int outInt;       if(int.TryParse(readData, out outInt))          return outInt       //...   }  

Answer by Adinochestva for Cast object to T


try

if (readData is T)      return (T)(object)readData;  

Answer by genki for Cast object to T


Actually, the responses bring up an interesting question, which is what you want your function to do in the case of error.

Maybe it would make more sense to construct it in the form of a TryParse method that attempts to read into T, but returns false if it can't be done?

    private static bool ReadData(XmlReader reader, string value, out T data)      {          bool result = false;          try          {              reader.MoveToAttribute(value);              object readData = reader.ReadContentAsObject();              data = readData as T;              if (data == null)              {                  // see if we can convert to the requested type                  data = (T)Convert.ChangeType(readData, typeof(T));              }              result = (data != null);          }          catch (InvalidCastException) { }          catch (Exception ex)          {              // add in any other exception handling here, invalid xml or whatnot          }          // make sure data is set to a default value          data = (result) ? data : default(T);          return result;      }  

edit: now that I think about it, do I really need to do the convert.changetype test? doesn't the as line already try to do that? I'm not sure that doing that additional changetype call actually accomplishes anything. Actually, it might just increase the processing overhead by generating exception. If anyone knows of a difference that makes it worth doing, please post!

Answer by baretta for Cast object to T


Actually, the problem here is the use of ReadContentAsObject. Unfortunately, this method does not live up to its expectations; while it should detect the most appropirate type for the value, it actually returns a string, no matter what(this can be verified using Reflector).

However, in your specific case, you already know the type you want to cast to, therefore i would say you are using the wrong method.

Try using ReadContentAs instead, it's exactly what you need.

private static T ReadData(XmlReader reader, string value)  {      reader.MoveToAttribute(value);      object readData = reader.ReadContentAs(typeof(T), null);      return (T)readData;  }  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.