Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以检查变量是否可以转换为指定的类型吗?_C#_Casting_Type Conversion - Fatal编程技术网

C# 我可以检查变量是否可以转换为指定的类型吗?

C# 我可以检查变量是否可以转换为指定的类型吗?,c#,casting,type-conversion,C#,Casting,Type Conversion,我试图验证传递的变量是否可以转换为特定类型。我尝试了以下方法,但无法将其编译,因此我认为我的方法是错误的(我是C#新手) 我基本上是在试图避免一个大规模的switch语句 switch(myType){ case "System.Int32": try { var convertedValue = Convert.ToInt32(myValue); } catch (Exception) {

我试图验证传递的变量是否可以转换为特定类型。我尝试了以下方法,但无法将其编译,因此我认为我的方法是错误的(我是C#新手)

我基本上是在试图避免一个大规模的switch语句

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

好的,基本上我有一个已知输入类型的db表,如下所示:

CREATE TABLE [dbo].[MetadataTypes] (
    [typeName]  VARCHAR (50)  NOT NULL,
    [dataType]  VARCHAR (50)  NOT NULL,
    [typeRegex] VARCHAR (255) NULL
);
其中可能包含以下数据:

"StartTime","System.DateTime",null
"TicketId","System.String","$[Ff][0-9]{7}^"
我的函数的输入是沿着

myInput = new KeyValuePair<string,string>("StartTime","31/12/2010 12:00");
myInput=新的KeyValuePair(“开始时间”,“31/12/2010 12:00”);
我需要检查KeyValuePair的值是否为MetaDataType所期望的正确数据类型

编辑答案:

莱昂非常接近我最终想出的解决办法

作为参考,我的函数现在如下所示:

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;

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

    return result;
}
public Boolean ValidateMetadata(KeyValuePair数据项)
{
//查找名称匹配的已知元数据
MetadataType类型=_repository.GetMetadataTypes().SingleOrDefault(t=>t.typeName==dataItem.Key);
如果(type==null){return false;}
//获取数据类型并尝试与传入的数据项匹配。
布尔值isCorrectType=false;
string typeString=type.dataType;
字符串dataValue=dataItem.Value;
尝试
{
var cValue=Convert.ChangeType(dataValue,Type.GetType(typeString));
isCorrectType=true;
}
抓住
{
isCorrectType=false;
}
//TODO:在此处根据可能的正则表达式进行验证。。。。
返回正确的类型;
}

我想这就是你想要的:

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
}
编辑:为了清楚起见,操作符
as
以以下方式使用


is
运算符将返回一个
布尔值,以指示被测对象是否为指定的类型或是否实现了指定的接口。这就像问编译器“我的变量是这种类型的吗?”:

as
运算符尝试执行转换,如果不能执行,则返回一个
null
引用。这就像告诉编译器“我想将此变量用作此类型”:

如果您尝试这样做:

var someString = "42";
// using Int32? because the type must be a reference type to be used with as operator
var someIntValue = someString as Int32?;
编译器将发出一个错误:

无法通过内置对话转换类型

您是否尝试过使用布尔返回值指示转换是否成功的方法来签出此链接:

is运算符用于检查对象的运行时类型是否与给定类型兼容。is运算符用于以下形式的表达式:


您可以使用什么?

您可以执行
int.TryParse()
功能:

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

if (parsed) {
    // Do something with myInt or other logic
}
使用“as”操作符尝试强制转换:

var myObject = something as String;

if (myObject != null)
{
  // successfully cast
}
else
{
  // cast failed
}
如果强制转换失败,则不会引发异常,但目标对象将为Null

编辑:

如果您知道需要哪种类型的结果,可以使用以下帮助器方法:

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;

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

    return result;
}
公共静态对象TryConvertTo(字符串输入)
{
对象结果=空;
尝试
{
结果=Convert.ChangeType(输入,typeof(T));
}
抓住
{
}
返回结果;
}
试试这个

return myType.IsInstanceOfType(myObject);

我知道这已经很古老了,但对于用现代方式寻找答案的人来说,会留下回复。从C#7中,您可以使用带有模式匹配的新开关()


您需要什么类型的数据?你需要处理哪一个?这不是强制转换,更像是转换,Int32只是我试图验证的类型的一个例子。它可以是DateTime、Boolean、Decimal等等@Nick:如果你总是来自
字符串
,你需要解析。您应该知道您希望它是什么类型,这就是您使用您提到的每种类型的
TryParse
方法的地方。唉,Convert.ChangeType(object,type)仅适用于实现IConvertible的对象在这种情况下,
is
运算符将不起作用,因为
字符串
int
是完全不同的类型。如果您知道它是什么类型,为什么还要费心解析?@321X,解析数字并不是为了弄清楚它是什么类型,但是您希望它是什么类型。所以您建议使用
TryTryParse()
?与
is
类似,您不能将
string
强制转换为
int
。即使解析成功,每次都会失败。您的编辑与我的解决方案非常接近:)我只需要从其名称获取要转换为的类型。@yoyo“as”运算符确实尝试强制转换。是不转换的类型。as运算符只适用于引用类型或可为空的类型,因此解决方案不能涵盖所有情况。@Leon他的意思是显式转换--
as
只会尝试“强制转换”到兼容的类型--它实际上不会将int转换为字符串(即使您将其装箱)-->as
不会返回新的/转换的对象。--它只返回具有不同类型句柄的同一对象(如果无法强制转换,则返回null)。这非常适合我的目的。我正在编写一个MVC验证器,需要检查传入验证器IsValid函数的值是否为给定(可能为空)类型。
public static Object TryConvertTo<T>(string input)
{
    Object result = null;
    try
    {
        result = Convert.ChangeType(input, typeof(T));
    }
    catch
    {
    }

    return result;
}
return myType.IsInstanceOfType(myObject);
        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;
        }