Nick
Nick

Reputation: 4223

Can I check if a variable can be cast to a specified type?

I am trying to verify whether a variable that is passed can be converted to a specific type. I have tried the following but can't get it to compile so I assume I'm going about it the wrong way (I'm new to C#)

string myType = "System.Int32";
string myValue = "42";

bool canBeCast = false;

try
{
  // try to convert the value to it's intended type to see if it's valid.
  var result = (Type.GetType(typeString))dataValue;
  canBeCast = true;
}
catch
{
  canBeCast = false;
}

I'm basically trying to avoid a massive switch statement along the lines of

  switch(myType){
    case "System.Int32":
      try
      {
        var convertedValue = Convert.ToInt32(myValue);
      }
      catch (Exception)
      {
        canBeConverted = false;
      }
      break;
    case "another type":
      ...
  }

EDIT:

Ok, basically I have a db table of known input types that looks like:

CREATE TABLE [dbo].[MetadataTypes] (
    [typeName]  VARCHAR (50)  NOT NULL,
    [dataType]  VARCHAR (50)  NOT NULL,
    [typeRegex] VARCHAR (255) NULL
);

which may have data such as

"StartTime","System.DateTime",null
"TicketId","System.String","$[Ff][0-9]{7}^"

And the input to my function would be a KeyValuePair along the lines of

myInput = new KeyValuePair<string,string>("StartTime","31/12/2010 12:00");

I need to check that the value of the KeyValuePair is of the correct datatype expected by the MetaDataType.

EDIT FOR ANSWER:

Leon got really close to the solution I finally came up with.

For reference my function now looks like this:

public Boolean ValidateMetadata(KeyValuePair<string, string> dataItem)
{

  // Look for known metadata with name match
  MetadataType type = _repository.GetMetadataTypes().SingleOrDefault(t => t.typeName == dataItem.Key);
  if (type == null) { return false; }

  // Get the data type and try to match to the passed in data item.
  Boolean isCorrectType = false;
  string typeString = type.dataType;
  string dataValue = dataItem.Value;

  try
  {
    var cValue = Convert.ChangeType(dataValue, Type.GetType(typeString));
    isCorrectType = true;
  }
  catch
  {
    isCorrectType = false;
  }

  //TODO: Validate against possible regex here....            

  return isCorrectType;

}

Upvotes: 82

Views: 130401

Answers (7)

Skylin R
Skylin R

Reputation: 2271

From C#7 You can use new switch with pattern matching (https://learn.microsoft.com/pl-pl/dotnet/csharp/pattern-matching)

        switch (myObject)
        {
            case PlayerObject playerObject:
                //this is player object type and can use also playerObject because it's already casted
                break;
            case EnemyObject enemyObject:
                //same here but we have enemy object type
                break;
            default:
                break;
        }

Upvotes: 3

Leon
Leon

Reputation: 3401

Use the "as" operator to attempt a cast:

var myObject = something as String;

if (myObject != null)
{
  // successfully cast
}
else
{
  // cast failed
}

If the cast fails, no exception is thrown, but the destination object will be Null.

EDIT:

if you know what type of result you want, you can use a helper method like this:

public static Object TryConvertTo<T>(string input)
{
    Object result = null;
    try
    {
        result = Convert.ChangeType(input, typeof(T));
    }
    catch
    {
    }

    return result;
}

Upvotes: 103

Jay Byford-Rew
Jay Byford-Rew

Reputation: 6014

Try this

return myType.IsInstanceOfType(myObject);

Upvotes: 14

evasilchenko
evasilchenko

Reputation: 1870

You can do the int.TryParse() function:

int myInt;
bool parsed = int.TryParse(myVariable, out myInt);

if (parsed) {
    // Do something with myInt or other logic
}

Upvotes: 1

Yuck
Yuck

Reputation: 50825

I think this is what you're looking for:

var myValue = "42";
int parsedValue;

if (Int32.TryParse(myValue, out parsedValue)) {
    // it worked, and parsedValue is equal to 42
}
else {
    // it did not work and parsedValue is unmodified
}

EDIT: Just to be clear, the operators is and as are used in the following ways...

The is operator will return a boolean value to indicate whether or not the object being tested either is the type specified or implements the interface specified. It's like asking the compiler "Is my variable this type?":

var someString = "test";
var result = someString is IComparable; // result will be true

The as operator attempts to perform the conversion, and returns a null reference if it can't. This is like telling the compiler "I would like to use this variable as this type":

var someString = "test";
var comparable = someString as IComparable; // comparable will be of type String

If you tried to do this:

var someString = "42";
// using Int32? because the type must be a reference type to be used with as operator
var someIntValue = someString as Int32?;

The compiler will issue an error:

Cannot convert type via a built-in converstion.

Upvotes: 8

321X
321X

Reputation: 3185

Checkout this link: http://msdn.microsoft.com/en-us/library/scekt9xw(v=vs.71).aspx

The is operator is used to check whether the run-time type of an object is compatible with a given type. The is operator is used in an expression of the form:

if (expression is type){
    // do magic trick
}

Something you can use?

Upvotes: 21

Ta01
Ta01

Reputation: 31610

Have you tried TryParse which has a boolean return value to indicate whether the conversion succeeded

Upvotes: 1

Related Questions