protected DecideTypesForStrings(TypeCompatibilityGroup compatibilityGroup, params Type[] typesSupportedSupported) { CompatibilityGroup = compatibilityGroup; if (typesSupportedSupported.Length == 0) { throw new ArgumentException("There must be at least one supported type"); } TypesSupported = new HashSet <Type>(typesSupportedSupported); }
/// <summary> /// Determines behaviour of abstract base. Call from derived classes to indicate what inter compatible Types you support parsing into / guessing /// </summary> /// <param name="culture"></param> /// <param name="compatibilityGroup">How your Type interacts with other Guessers, e.g. can you fallback from one to another</param> /// <param name="typesSupported">All the Types your guesser supports e.g. multiple sizes of int (int32, int16 etc). These should not overlap with other guessers in the app domain</param> protected DecideTypesForStrings(CultureInfo culture, TypeCompatibilityGroup compatibilityGroup, params Type[] typesSupported) { Culture = culture; Settings = new GuessSettingsFactory().Create(); CompatibilityGroup = compatibilityGroup; if (typesSupported.Length == 0) { throw new ArgumentException(SR.DecideTypesForStrings_DecideTypesForStrings_DecideTypesForStrings_abstract_base_was_not_passed_any_typesSupported_by_implementing_derived_class); } TypesSupported = new HashSet <Type>(typesSupported); }
public void AdjustToCompensateForValue(object o) { if (o == null) { return; } if (o == DBNull.Value) { return; } //if we have previously seen a hard typed value then we can't just change datatypes to something else! if (IsPrimedWithBonafideType) { if (CurrentEstimate != o.GetType()) { throw new DataTypeComputerException("We were adjusting to compensate for object " + o + " which is of Type " + o.GetType() + " , we were previously passed a " + CurrentEstimate + " type, is your column of mixed type? this is unacceptable"); } } var oToString = o.ToString(); var oAsString = o as string; //we might need to fallback on a string later on, in this case we should always record the maximum length of input seen before even if it is acceptable as int, double, dates etc _stringLength = Math.Max(Length, GetStringLength(oToString)); //if it's a string if (oAsString != null) { //ignore empty ones if (string.IsNullOrWhiteSpace(oAsString)) { return; } //if we have already fallen back to string then just stick with it (theres no going back up the ladder) if (CurrentEstimate == typeof(string)) { return; } var result = _typeDeciders.Dictionary[CurrentEstimate].IsAcceptableAsType(oAsString, DecimalSize); //if the current estimate compatible if (result) { _validTypesSeen = _typeDeciders.Dictionary[CurrentEstimate].CompatibilityGroup; if (CurrentEstimate == typeof(DateTime)) { _stringLength = Math.Max(_stringLength, MinimumLengthRequiredForDateStringRepresentation); } return; } //if it isn't compatible, try the next Type ChangeEstimateToNext(); //recurse because why not AdjustToCompensateForValue(oAsString); } else { //if we ever made a descision about a string inputs then we won't accept hard typed objects now if (_validTypesSeen != TypeCompatibilityGroup.None || CurrentEstimate == typeof(string)) { throw new DataTypeComputerException("We were adjusting to compensate for hard Typed object '" + o + "' which is of Type " + o.GetType() + ", but previously we were passed string values, is your column of mixed type? that is unacceptable"); } //if we have yet to see a proper type if (!IsPrimedWithBonafideType) { CurrentEstimate = o.GetType();//get its type IsPrimedWithBonafideType = true; } //if we have a decider for this lets get it to tell us the decimal places (if any) if (_typeDeciders.Dictionary.ContainsKey(o.GetType())) { _typeDeciders.Dictionary[o.GetType()].IsAcceptableAsType(oToString, DecimalSize); } } }