开发者

In .NET String.Format is accepting objects of a type that don't match the format string

开发者 https://www.devze.com 2023-03-18 08:45 出处:网络
I have a function that is getting passed a String and a DataRow. The String is a custom formatter. The idea is to do this

I have a function that is getting passed a String and a DataRow.

The String is a custom formatter. The idea is to do this

String.Format(passed_in_开发者_JAVA技巧String, DataRow("ColumnINeed"))

The reason this is being done is at this point we have no idea what the column contains.

However, if the formatter is "{0:MM/dd/yyyy}" and the DataRow("ColumnINeed") is an integer containing 42, String.Format is returning: MM/dd/yyyy

In this situation I need it to throw an exception instead of returning nonsense.

Is there anyway to make String.Format throw an exception if the object does not match what the format string is expecting?


You need to become familiar with your data. If you're in a situation where the data could truly be anything at anytime, you're in a bad spot. Frankly, I rather doubt you are in that situation. At least, I'm extremely hopeful you are not.

If it is exceptional for the data in the column to not be a date, then pull it out as a date. Don't pull it out and hope it nicely formats to one, pull it out as one!

DateTime myDate = (DateTime)datarow["MyColumn"]; // C#
Dim myDate As DateTime = CType(datarow("MyColumn"), DateTime) 'VB

Even if you find your data to be stringly typed, immediately parse it. Set the expectation that the value is a date in your code. When it isn't, it will create an exception.

Edit: Chris mentions a good alternate suggestion in the comments. You can also write

DateTime myDate = datarow.Field<DateTime>("MyColumn");

The benefit here is what if the column allowed nulls?

DateTime? myDate = (DateTime?)datarow["MyColumn"]; // C#
Dim myDate = CType(datarow("MyColumn"), DateTime?) 'VB

Here, you may get "Specified Cast Not Valid" if row holds DBNull.

DateTime? myDate = datarow.Field<DateTime?>("MyColumn"); // C#
Dim myDate = datarow.Field(of DateTime?)("MyColumn") 'VB

This alternate handles DBNull appropriately.


The reason this is being done is at this point we have no idea what the column contains.

So I guess the data type of the column can differ for every call of your function. In that case, pass the data type along with the function as well, i.e., make it generic.

Here's an example. Instead of

function myCoolFormatter(string passed_in_String, DataRow drow) { 
    object data = drow("ColumnINeed");
    return string.Format(passed_in_String, data);
}

use

function myCoolFormatter<T>(string passed_in_String, DataRow drow) { 

    // will raise an exception if ColumnINeed is not of type T
    T data = drow.Field<T>("ColumnINeed");

    return string.Format(passed_in_String, data);
}

Your function can then be called like this:

var myFormattedString = myCoolFormatter<DateTime>("Date: {0:MM/dd/yyyy}",
                                                  dataRowWithDateTimes);
0

精彩评论

暂无评论...
验证码 换一张
取 消