C#, dynamic return type
What I need is a method that can return a type (no object, cause no casting开发者_开发知识库 allowed) following a condition. Here is an example:
??? right (string fullStr, int endPosition)
{
string tmpStr = "";
tmpStr = fullStr.Substring(endPosition);
if(tmpStr.Length == 1)
return tmpStr[0]; //return a char!!
else
return tmpStr; //return a string!!
}
I tried generics but I was only able to return the type that was coming in, (if a char came in a char was returned, and if a string came in a string was returned). I tried this:
public static T right<T>(T stringToCheck, int endPosition)
{
if (typeof(T).ToString() == "System.String")
{
string fullString = (string)((object)stringToCheck);
string response = "";
response = fullString.Substring(endPosition);
if (response.Length == 1)
{
return (T)((object)response[0]);
}
else
return (T)((object)response);
}
return stringToCheck;
}
I can't use typecasting (returning an object), cant use ref params.
Calls to the method have to stay the same:
right(stringOrChar,int) -> returns string or char.
Thank You
I don't think it's theoretically possible. You could use "dynamic" in C# 4, but if you're not there yet, you can't do that.
If it could return either a string or a character, then it has to be an object that both of those descend from, of which "object" is your only choice. And then you'd have to do casts.
C# (3.5 and previous) needs to know what the single return type of the method is so that it can do checking on the calling method. And in fact, in C#4, when you say "dynamic" it actually uses "object" underneath.
You could create a custom class/struct that has both
public class StringOrChar
{
char charValue;
string stringValue;
bool isString;
}
But it's kludgy.
Why do you want to have different return types?
The return type of a function must be typed. As with any other variable or operation, any type that inherits from the specified type is a valid return value (which is why object
allows anything as a value).
The logistics of the caller wouldn't make much sense; how would you know whether to type your variable as a char
or a string
in your example?
Is there a particular reason that you can't return a string
in all cases?
Your can use out
parameters. or return a type that contains both variations.
there are alot of " left(str,1) < 'x' " but other times it is simply abc = left(str,3)
In this particular case, you could just return a single-character string. Comparing strings operates on their lexicographical order, so there's no specific need to use chars here (unless, of course, the original author was using polymorphism to treat the chars differently from strings, in which case you have my sympathies).
methods can only - as far as i know - return one type
so return object and cast is the logical alternative
however, note that if your design has forced you into this predicament, there may be a flaw in it; perhaps some more details can help us help you
note: jon skeet is immune from all such restrictions
Enriquev,
There is not a way to implement the right without changing the syntax from VBA. You could specify what return type you wanted, but this is essentially casting...
public static U right<T, U>(T input, int index)
{
...
return (U)returnVariable;
}
I don't really think this solves your problem.
Is it possible to do a regex replace of all single characters surrounded by single quotes? This will make the characters into strings and allow your comparison operators to work.
What about this:
string right(string fullStr, int endPosition, out bool oneChar)
{
string result = fullStr.Substring(endPosition);
oneChar = result.Length == 1;
return result;
}
This should work:
public static dynamic right(string fullStr, int endPosition)
{
string tmpStr = "";
tmpStr = fullStr.Substring(endPosition);
if (tmpStr.Length == 1)
return tmpStr[0]; //return a char!!
else
return tmpStr; //return a string!!
}
Testing this code:
static void Main(string[] args)
{
var str = right("Hello", 3);
Console.WriteLine(str.GetType()); // System.String
var ch = right("Hello", 4);
Console.WriteLine(ch.GetType()); // System.Char
}
Are you trying to do this?
/// <summary>
/// Emulates VB Right Function
/// Returns a string containing a specified number of characters from the right side of a string.
/// </summary>
/// <param name="s"></param>
/// <param name="length">The number of characters to return.</param>
/// <returns>
/// The right <paramref name="length"/> number of characters from the string.
/// If the string has less than or equal to <paramref name="length"/> number of characters,
/// an empty string is returned.
/// </returns>
public static string Right(this string s, int length)
{
return length > s.Length ? string.Empty : s.Substring(s.Length - length);
}
When calling this method, you could do:
string myString = "Test String";
string returnedString = mystring.Right(1);
char? myChar = returnedString.Length == 1 ? returnedString[0] : null;
bool isReturnValueAChar = myChar.HasValue;
精彩评论