как можно вернуть конкретный тип значения без изменения сигнатуры?
В данном случае - никак.
T
- это generic параметр для подстановки во время компиляции. Он означает конкретный тип.
Так как никаких ограничений на него не выставлено, то считается, что может в него быть вставлено абсолютно что-угодно. Но возвращаемые значения должны уметь конвертироваться в этот возвращаемый тип, например, если
T
- long, то
ParseInt
сработает, т.к.
int
конвертируется к long (неявно и явно), а
DateTime
к
long
просто так нет. А теперь вместо
T
подставь
byte
или какой-нибудь класс и подумай - можно ли
int
к этому классу сконвертировать.
Пишу парсер
Когда я писал свой парсер, то делал базовый класс с абстрактным свойством, которое показывает что это за тип, и для каждого возможного значения - отдельный класс, который наследуется от базового. Чтобы понимать, что в результате пришло - смотрю на это поле.
Дополнительно, в данном случае лучше применять какую-нидудь фабрику этих парсеров, т.к. в рантайме через рефлексию определять свой тип и на основании него парсить - такое себе.
Например, так можно
enum TokenType
{
Int,
Decimal,
DateTime,
}
public abstract class ParseResult
{
public abstract TokenType Type { get; }
}
public class IntParseResult: ParseResult
{
public override TokenType Type => TokenType.Int;
public int Value { get; }
IntParseResult(int value)
{
Value = value;
}
}
public class DecimalParseResult: ParseResult
{
public override TokenType Type => TokenType.Decimal;
public decimal Value { get; }
DecimalParseResult(decimal value)
{
Value = value;
}
}
public class DateTimeParseResult: ParseResult
{
public override TokenType Type => TokenType.DateTime;
public DateTime Value { get; }
DateTimeParseResult(DateTime value)
{
Value = value;
}
}
public interface IParser
{
ParseResult Parse(string str);
}
public class IntParser: IParser
{
public ParseResult Parse(string str) => ParseInt(str);
}
public class DecimalParser: IParser
{
public ParseResult Parse(string str) => ParseDecimal(str);
}
public class DateTimeParser: IParser
{
public ParseResult Parse(string str) => ParseDateTime(str);
}
public static class MyParser
{
private static IParser GetParserFor(string str) { /* .... */ };
public static ParseResult Parse(string str)
{
var parser = GetParserFor(str);
return parser.Parse(str);
}
}
Я рекомендую убрать этот статический парсер и вынести решение о том какой парсер использовать выше по иерархии вызовов, либо пересмотреть логику парсинга, т.к. просто посмотреть на строку и понять как парсить - не самое эффективное решение.