2009-11-23 18 views
5

Lo que necesito es un método que puede devolver un tipo (sin objeto, porque no se permite la conversión) después de una condición. He aquí un ejemplo:C#, tipo de retorno dinámico

??? 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!! 
} 

Probé genéricos, pero yo sólo era capaz de devolver el tipo que venía en, (si es un char se produjo en un char fue devuelto, y si una cadena se produjo en una cadena fue devuelto) yo probamos este:

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; 
    } 

no puedo usar encasillamiento (volviendo un objeto), cant params uso ref.

llamadas al método tienen que permanecer el mismo:

right(stringOrChar,int) -> returns string or char. 

Gracias

+0

tal vez usted podría ayudarnos. ¿Por qué quieres tener múltiples tipos de devolución? ¿Por qué quieres un char en algunas circunstancias y una cadena en otras? – McKay

+0

Ok, la razón por la que necesito esto es porque estoy portando un montón de código, la sintaxis es principalmente compatible, pero tengo que saber si es posible hacerlo porque hay muchas "left (str, 1) <'x '' pero otras veces es simplemente abc = left (str, 3). Parece que no hay una distinción clara entre un char y una cadena en el idioma de donde proviene. El objetivo aquí es no tocar el código SI ES POSIBLE, pero no es porque no sé cómo no es posible :-) – Enriquev

Respuesta

7

El tipo de devolución de una función debe estar escrito. Al igual que con cualquier otra variable u operación, cualquier tipo que herede del tipo especificado es un valor de retorno válido (razón por la cual object permite algo como un valor).

La logística de la persona que llama no tendría mucho sentido; ¿Cómo sabría si escribe su variable como char o string en su ejemplo?

¿Existe alguna razón particular por la que no se pueda devolver un string en todos los casos?

11

no creo que es teóricamente posible. Puedes usar "dinámico" en C# 4, pero si aún no estás allí, no puedes hacer eso.

Si puede devolver una cadena o un carácter, entonces tiene que ser un objeto del que ambos descienden, de los cuales "objeto" es su única opción. Y luego tendrías que hacer moldes.

C# (3.5 y anteriores) necesita saber cuál es el tipo de retorno único del método para que pueda verificar el método de llamada. Y, de hecho, en C# 4, cuando dice "dinámico", en realidad usa "objeto" debajo.

Se puede crear una clase/estructura personalizada que tiene tanto

public class StringOrChar 
{ 
    char charValue; 
    string stringValue; 
    bool isString; 
} 

Pero es kludgy.

¿Por qué desea tener diferentes tipos de devolución?

2

Puede usar los parámetros out. o devuelve un tipo que contiene ambas variaciones.

1

métodos sólo pueden - como lo que yo sé - volver un tipo

así regresar objeto y el reparto es la lógica alternativa

sin embargo, tenga en cuenta que si su diseño se ha obligado a esta situación, puede haber ser un defecto en eso; tal vez algunos detalles pueden ayudar a ayudarle

nota: Jon Skeet es inmune a todas esas restricciones

+10

Jon Skeet también tiene teclas de cambio y puntos en su teclado. –

+0

@ [Robert Harvey]: Jon Skeet no necesita un teclado; él tiene una interfaz neural directa cortesía de Google UK .... y si los e cummings le molestan, siéntase libre de editarlos. ;-) –

0

Qué tal esto:

string right(string fullStr, int endPosition, out bool oneChar) 
{ 
    string result = fullStr.Substring(endPosition); 
    oneChar = result.Length == 1; 
    return result; 
} 
-1

¿Estás tratando de hacer esto?

/// <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); 
} 

Cuando se llama a este método, se puede hacer:

string myString = "Test String"; 
string returnedString = mystring.Right(1); 
char? myChar = returnedString.Length == 1 ? returnedString[0] : null; 
bool isReturnValueAChar = myChar.HasValue; 
2

hay un montón de "izquierda (str, 1) < 'x'", pero otras veces es simplemente abc = izquierda (str, 3)

En este caso particular, podría simplemente devolver una cadena de un solo carácter. La comparación de cadenas opera según su orden lexicográfico, por lo que no hay necesidad específica de utilizar caracteres aquí (a menos que, por supuesto, el autor original usara polimorfismo para tratar los caracteres de forma diferente a las cadenas, en cuyo caso tienes mis simpatías).

0

Enriquev,

No hay una manera de poner en práctica el derecho sin cambiar la sintaxis de VBA. Se podría especificar qué tipo de retorno que quería, pero esto es esencialmente fundición ...

public static U right<T, U>(T input, int index) 
{ 
... 
return (U)returnVariable; 
} 

Realmente no creo que esto resuelve su problema.

¿Es posible hacer un reemplazo de expresiones regulares de todos los caracteres individuales rodeados por comillas simples? Esto convertirá los caracteres en cadenas y permitirá que los operadores de comparación trabajen.

0

Esto debería funcionar:

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!! 
    } 

Prueba este código:

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 
    }