user1679941
user1679941

Reputation:

How can I throw an exception in C# if a string does not match a format?

If I do the following assignement when vm.TempRowKey is null then will the value of newRowKey be null?

var newRowKey = vm.TempRowKey.DotFormatToRowKey();

Also is there a way that I can make the following throw an exception if the dotFormatRowKey does not have the format x.x where x is a number?

public static string DotFormatToRowKey(this string dotFormatRowKey) {
    var splits = dotFormatRowKey.Split('.')
                 .Select(x => String.Format("{0:d2}", Int32.Parse(x)))
                 .ToList();
    return String.Join(String.Empty, splits.ToArray());
}

Upvotes: 3

Views: 2809

Answers (6)

Henk Holterman
Henk Holterman

Reputation: 273494

when vm.TempRowKey is null

Then TempRowKey.DotFormatToRowKey(); will throw a null-reference exception.

throw an exception if the dotFormatRowKey does not have the format x.x where x is a number?

public static string DotFormatToRowKey(this string dotFormatRowKey) 
{
    if (dotFormatRowKey == null)
        throw new ArgumentNullException("dotFormatRowKey");    

    // maybe @"^\d\d?\.\d\d?$" is a beter regex. 
    // accept only 1|2 digits and nothing before|after
    if (! Regex.IsMatch(dotFormatRowKey, @"\d+\.\d+"))  
       throw new ArgumentException("Expected ##.##, was " + dotFormatRowKey);

    var splits = dotFormatRowKey.Split('.')
                 .Select(x => String.Format("{0:d2}", Int32.Parse(x)))
                 .ToList();  // ToList() is never needed

    // ToArray() not needed in Fx >= 4.0
    return String.Join(String.Empty, splits.ToArray()); 
}

Small detail: You are using both ToList() and ToArray() on splits. That is double work and in .NET 4 you don't need either.

Upvotes: 3

Guffa
Guffa

Reputation: 700592

No, the result will not be null. You can call the extension method with a null reference, but the extension method isn't written to handle null values, so you will get an eception when you try to use the Split method on the null reference.

To check for the format "x.x" you can check the length of the result of the Split, then use TryParse to check if the values were possible to parse:

public static string DotFormatToRowKey(this string dotFormatRowKey) {
  var splits = dotFormatRowKey.Split('.');
  if (splits.Length != 2) {
    throw new FormatException("The string should contain one period.");
  }
  var s = splits.Select(x => {
    int y;
    if (!Int32.TryParse(x, out y)){
      throw new FormatException("A part of the string was not numerical");
    }
    if (y < 0 || y > 99) {
      throw new FormatExcetpion("A number was outside the 0..99 range.");
    }
    return y.ToString("d2");
  }).ToArray();
  return String.Concat(s);
}

Upvotes: 3

BrunoLM
BrunoLM

Reputation: 100361

You have to check if it is null, or else you will get an exception.

if (null == dotFormatRowKey)
    return null;

And you can validate a pattern using Regex.

Regex.IsMatch(input, "^\d+\.\d+$");

See

Upvotes: 0

Dmytro
Dmytro

Reputation: 17196

public static string DotFormatToRowKey(this string dotFormatRowKey)
        {
            Regex validationRegex = new Regex(@"\d.\d");
            if (!validationRegex.Match(dotFormatRowKey).Length.Equals(dotFormatRowKey.Length)) throw new FormatException("Input string does not support format x.x where x is number");

            var splits = dotFormatRowKey.Split('.')
                .Select(x => String.Format("{0:d2}", Int32.Parse(x)))
                .ToList();
            return String.Join(String.Empty, splits.ToArray());
        }

Upvotes: 0

ChaseMedallion
ChaseMedallion

Reputation: 21764

If I do the following assignement when vm.TempRowKey is null then will the value of newRowKey be null?

This should cause a NullReferenceException, because dotFormatRowKey will be null and then you'll be calling Split() (which is not an extension method) on a null value.

Also is there a way that I can make the following throw an exception if the dotFormatRowKey does not have the format x.x where x is a number?

Currently, the use of int.Parse() enforces that you have only integer values and "."'s. It does not enforce that all integer values are the same, nor that there is only 1 "." (e. g. this would not throw on 1.2.3). If you want to add additional error checking, this would be easy to do:

// test that all int values were the same (not sure if you want this but you said x.x)
if (splits.Distinct().Count() > 1) { throw new ExceptionOfSomeSort("error"); }

// test that you have exactly two values
if (splits.Count != 2) { throw new ExceptionOfSomeSort("error"); }

Another option would be to validate the entire string up front with a regular expression, something like:

@"\d+\.\d+"

Upvotes: 0

Artless
Artless

Reputation: 4568

For your first question.. Try and see what happens.

Second question, you can use TryParse, and if that fails simply.. Throw an exception.

Upvotes: 0

Related Questions