C# 检查字符串是否可以转换为给定类型

C# 检查字符串是否可以转换为给定类型,c#,C#,我必须创建一个API,在该API中,我需要向用户提供正确的消息。如果用户没有在GET请求中提供必需的参数,我还需要确保用户在参数中提供了正确的值,这些值可以是整数、字符串、日期或枚举 因此,我创建了一个类SearchParameters,其中列出了请求参数的相关信息 private static class SearchParameters { public static List<ParamInfo> ParamList = new List<ParamInfo>

我必须创建一个API,在该API中,我需要向用户提供正确的消息。如果用户没有在GET请求中提供必需的参数,我还需要确保用户在参数中提供了正确的值,这些值可以是整数、字符串、日期或枚举

因此,我创建了一个类SearchParameters,其中列出了请求参数的相关信息

private static class SearchParameters
{
    public static List<ParamInfo> ParamList = new List<ParamInfo>
    {
        new ParamInfo {Name ="location", IsMandatory = true , ExpecteDataType = typeof(ulong) } ,
        new ParamInfo {Name ="service", IsMandatory = true  , ExpecteDataType = typeof(ServiceType)} ,
        new ParamInfo {Name ="start", IsMandatory = true  , ExpecteDataType = typeof(DateTimeOffset)} ,
        new ParamInfo {Name ="appointmentType", IsMandatory = true  , ExpecteDataType = typeof(AppointmentType)} ,
        new ParamInfo {Name ="status", IsOptional = true  , ExpecteDataType = typeof(string)} ,
        new ParamInfo {Name ="end", IsOptional = true  , ExpecteDataType = typeof(DateTimeOffset)} ,
        new ParamInfo {Name ="clinicianGender", IsOptional = true , ExpecteDataType = typeof(AdministrativeGender)}   ,
        new ParamInfo {Name ="_sort", IsForSorting = true , ExpecteDataType = typeof(string)},
        new ParamInfo {Name ="_count", IsForPaging = true , ExpecteDataType = typeof(uint)}
    };
}
当用户请求我在元组列表中提供参数时,
Item1
Item2
都是字符串,
Item1
是查询参数的名称,
Item2
是用户提供的值

如何确保参数值(即
Item2
)的数据类型正确

我试过这样的方法:

// Data tye verification
foreach (ParamInfo info in SlotSearchParameters.ParamList)
{
    Tuple<string, string> param = searchparams.Parameters.Where(x => x.Item1.ToLower() == info.Name).FirstOrDefault();
    if (param != null)
    {
        Type expectedType = info.ExpecteDataType;
        // how can we check if the value of type of x.Item1 is as expected 
        // Can't procede
    }
}
foreach (ParamInfo info in SlotSearchParameters.ParamList)
{
    Tuple<string, string> param = searchparams.Parameters.Where(x => x.Item1.ToLower() == info.Name).FirstOrDefault();

    if (param != null &&
        Validator(x.Item1) //
    {
        //whatever
    }
}
//数据类型验证
foreach(SlotSearchParameters.ParamList中的ParamInfo信息)
{
Tuple param=searchparams.Parameters.Where(x=>x.Item1.ToLower()==info.Name.FirstOrDefault();
如果(参数!=null)
{
类型expectedType=info.ExpecteDataType;
//如何检查x.Item1类型的值是否如预期的那样
//无法继续
}
}

但是由于
x.Item1
始终是提供的值的字符串表示形式,可以是Date、Int或string等,我不知道该怎么办?

出于您问题中所述的目的,您应该使用
Parse()
(re:)或
TryParse()
(re:)方法,例如
int32.Parse([your_string])


希望这会有所帮助。

您可以向
ParamInfo
类添加验证程序:

public class ParamInfo
{
    public string Name { get; set; }
    public bool IsMandatory { get; set; }
    public bool IsRequired { get; set; }
    public bool IsOptional { get; set; }
    public bool IsForSorting { get; set; }
    public bool IsForPaging { get; set; }
    public Type ExpecteDataType { get; set; }
    public Predicate<string> Validator { get; set; }
}
公共类ParamInfo
{
公共字符串名称{get;set;}
公共布尔是强制性的{get;set;}
需要公共布尔值{get;set;}
公共布尔等民族{get;set;}
公共bool用于排序{get;set;}
公共bool用于分页{get;set;}
公共类型ExpecteDataType{get;set;}
公共谓词验证器{get;set;}
}
现在:

public static List<ParamInfo> ParamList = new List<ParamInfo>
{
    new ParamInfo { Name ="location",
                   IsMandatory = true, 
                   ExpecteDataType = typeof(ulong),
                   Validator = s => s != null && ulong.TryParse(s, out var _); }
public static List ParamList=新列表
{
新的ParamInfo{Name=“location”,
IsMandatory=正确,
ExpecteDataType=类型(ulong),
Validator=s=>s!=null&&ulong.TryParse(s,out var)}
您可以这样使用它:

// Data tye verification
foreach (ParamInfo info in SlotSearchParameters.ParamList)
{
    Tuple<string, string> param = searchparams.Parameters.Where(x => x.Item1.ToLower() == info.Name).FirstOrDefault();
    if (param != null)
    {
        Type expectedType = info.ExpecteDataType;
        // how can we check if the value of type of x.Item1 is as expected 
        // Can't procede
    }
}
foreach (ParamInfo info in SlotSearchParameters.ParamList)
{
    Tuple<string, string> param = searchparams.Parameters.Where(x => x.Item1.ToLower() == info.Name).FirstOrDefault();

    if (param != null &&
        Validator(x.Item1) //
    {
        //whatever
    }
}
foreach(SlotSearchParameters.ParamList中的ParamInfo信息)
{
Tuple param=searchparams.Parameters.Where(x=>x.Item1.ToLower()==info.Name.FirstOrDefault();
if(param!=null&&
验证器(x.Item1)//
{
//随便
}
}
}

如何确保参数(即Item2)的值是正确的数据类型

  • 您可能会让用户很难实际输入错误的数据类型。例如,如果他们在表单中键入内容,而您要求输入日期–如果他们在该字段中键入一些不合理的内容,请将其设置为无法提交表单
  • 如果他们输入了一些不感兴趣的内容,或者
  • 如果输入值不真实,可以阻止创建ParamInfo对象。有关一些示例,请参见下文
  • 旁注:您在ParamInfo类中实际将数据存储在哪里?如果您实际上将变量存储为int、date或enum等,那么使用此变量将无需使用ExpectedDataType变量。我希望这是有意义的。换句话说,是否要将item1.value作为字符串存储在ParamInfo中类还是非类?还是要将其存储为实际数字、日期或枚举
  • 用户是否可能意外输入错误的ParamInfo.Name值
  • 无论如何,这里有一些想法希望能帮助你:

    internal class Program
    {
        private static void Main(string[] args)
        {
            List<Tuple<string, string>> userInputValues = new List<Tuple<string, string>>(); // obviously implement the correct user values here
    
            // This is the money below.
            // you'll have only valid ParamInfo objects here:
    
            List<ParamInfo> paramFactory = new ParamInfoFactory(userInputValues).ValidParameters;         
        }
    
        public class ParamInfo
        {
            public string Name { get; set; }
            public bool IsMandatory { get; set; }
            public bool IsRequired { get; set; }
            public bool IsOptional { get; set; }
            public bool IsForSorting { get; set; }
            public bool IsForPaging { get; set; }
    
            public Type ExpecteDataType { get; set; } // <--- you really don't need this.
    
            // where are you storing the item1.value?
            // are you storing it as a string, or as the proper type that it represents?
        }
        public class ParamInfoFactory
        {
            public List<ParamInfo> ValidParameters { get; set; }
    
            public ParamInfoFactory(List<Tuple<string, string>> userSuppliedValues)
            {
                ValidParameters = new List<ParamInfo>();
                foreach (Tuple<string, string> userValue in userSuppliedValues)
                {
                    if (UserInputValuesAreValid(userValue))
                    {
                        // all the values are valid. you can now create and add the parameters to your list.
                        // remember to instantiate it as you wish with the right values etc in there.
                        ValidParameters.Add(new ParamInfo());
                    }
                }
            }
            private bool UserInputValuesAreValid(Tuple<string, string> userValue)
            {
                return IsNameValid(userValue.Item1) && IsDataValid(userValue.Item2);
            }
    
            private bool IsDataValid(string data)
            {
                return IsValidDate(data) || IsValidNumber(data); // you can also implement the IsValidEnum or any other method you want
            }
    
            private static bool IsValidDate(string data)
            {
                DateTime dateValue;
                bool isDate = DateTime.TryParse(data, out dateValue);
                return isDate;
            }
    
            //private static bool IsEnum(string data)
            //{
            //    Colors colorValue;
            //    bool isEnum = Enum.TryParse(data, out colorValue);
            //    return isEnum;
            //}
    
            private static bool IsValidNumber(string data)
            {
                int number;
    
                bool isNumber = Int32.TryParse(data, out number);
                return isNumber;
            }
    
            private bool IsNameValid(string userInputName)
            {
                return SearchParameters.ParamList.Any(paramInfo => paramInfo.Name == userInputName.ToLower());
            }
    
            private static class SearchParameters
            {
                public static List<ParamInfo> ParamList = new List<ParamInfo>
                {
                    new ParamInfo {Name ="location", IsMandatory = true , ExpecteDataType = typeof(ulong) } ,
                    new ParamInfo {Name ="service", IsMandatory = true  , ExpecteDataType = typeof(ServiceType)} ,
                    new ParamInfo {Name ="start", IsMandatory = true  , ExpecteDataType = typeof(DateTimeOffset)} ,
                    new ParamInfo {Name ="appointmentType", IsMandatory = true  , ExpecteDataType = typeof(AppointmentType)} ,
                    new ParamInfo {Name ="status", IsOptional = true  , ExpecteDataType = typeof(string)} ,
                    new ParamInfo {Name ="end", IsOptional = true  , ExpecteDataType = typeof(DateTimeOffset)} ,
                    new ParamInfo {Name ="clinicianGender", IsOptional = true , ExpecteDataType = typeof(AdministrativeGender)}   ,
                    new ParamInfo {Name ="_sort", IsForSorting = true , ExpecteDataType = typeof(string)},
                    new ParamInfo {Name ="_count", IsForPaging = true , ExpecteDataType = typeof(uint)}
                };
            }
        }
    }
    
    内部类程序
    {
    私有静态void Main(字符串[]args)
    {
    List userInputValues=new List();//显然在这里实现正确的用户值
    //这是下面的钱。
    //此处只有有效的ParamInfo对象:
    List paramFactory=新的ParamInfoFactory(userInputValues).ValidParameters;
    }
    公共类ParamInfo
    {
    公共字符串名称{get;set;}
    公共布尔是强制性的{get;set;}
    需要公共布尔值{get;set;}
    公共布尔等民族{get;set;}
    公共bool用于排序{get;set;}
    公共bool用于分页{get;set;}
    
    公共类型ExpecteDataType{get;set;}//我有一个字符串和一个类型变量,类型变量可以是string、Int、DateTime等类型。我们在类型类上没有任何直接的解析方法。那么您的业务逻辑有严重缺陷,简单明了。您应该先修复您的业务逻辑。如果您有更多问题,请标记此问题的答案并将其分开发布非常感谢。非常棒!您的解决方案非常优雅。我曾考虑使用反射,但使用委托的建议确实简化了一切。我没有使用C#7,因此无法使用不在乎(解析结果)由于TryParse方法的特性,我通过在String类上添加一些扩展方法来实现这一点。谢谢you@JavidAhmad很高兴它有帮助!