2009-11-23 12 views
5

Was ich brauche, ist eine Methode, die nach einer Bedingung einen Typ zurückgeben kann (kein Objekt, weil kein Casting erlaubt ist). Hier ein Beispiel:C#, dynamischer Rückgabetyp

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

ich Generika versucht, aber ich war nur in der Lage, die Art zurückzugeben, die in kommen würden, (wenn ein Zeichen in einem char kommt zurückgegeben wurde, und wenn eine Zeichenkette in einem String kommt, war zurückgekehrt). Ich versuchte dies:

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

ich nicht typecasting (Rückkehr ein Objekt) verwenden können, kann nicht params Verwendung ref.

Anrufe an die Methode die gleiche bleiben:

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

Danke

+0

Vielleicht aus Sie uns helfen könnten. Warum möchten Sie mehrere Rückgabetypen haben? Warum willst du in manchen Fällen einen Char und in anderen eine Saite? – McKay

+0

OK, der Grund, warum ich das brauche, ist, weil ich viel Code portiere, Syntax ist meistens kompatibel, aber ich muss wissen, ob es möglich ist, dies zu tun, weil es viele "links (str, 1) <'x gibt '"aber zu anderen Zeiten ist es einfach abc = links (str, 3). Es scheint keine klare Unterscheidung von einem Zeichen zu einer Zeichenkette in der Sprache zu geben, von der es kommt. Das Ziel hier ist, den Code WENN MÖGLICH nicht zu berühren, aber es ist nicht, weil ich nicht weiß, wie das nicht möglich ist :-) – Enriquev

Antwort

7

Der Rückgabetyp einer Funktion muss eingegeben werden. Wie bei jeder anderen Variable oder Operation ist jeder Typ, der vom angegebenen Typ erbt, ein gültiger Rückgabewert (deshalb erlaubt object alles als Wert).

Die Logistik des Anrufers würde nicht viel Sinn machen; Wie würden Sie wissen, ob Sie in Ihrem Beispiel Ihre Variable als char oder string eingeben?

Gibt es einen besonderen Grund, dass Sie in keinem Fall eine string zurückgeben können?

11

Ich glaube nicht, dass es theoretisch möglich ist. Sie könnten "dynamisch" in C# 4 verwenden, aber wenn Sie noch nicht da sind, können Sie das nicht tun.

Wenn es entweder eine Zeichenfolge oder ein Zeichen zurückgeben kann, dann muss es ein Objekt sein, von dem beide abstammen, von denen "object" die einzige Wahl ist. Und dann müsstest du Abgüsse machen.

C# (3.5 und früher) muss wissen, was der einzelne Rückgabetyp der Methode ist, so dass es die aufrufende Methode überprüfen kann. Und tatsächlich, in C# 4, wenn Sie "dynamisch" sagen, verwendet es tatsächlich "Objekt" darunter.

Sie können eine benutzerdefinierte Klasse/Struktur schaffen, die sowohl

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

hat Aber es ist kludgy.

Warum möchten Sie unterschiedliche Rückgabetypen haben?

2

Sie können out Parameter verwenden. oder geben Sie einen Typ zurück, der beide Varianten enthält.

1

Methoden nur können - soweit ich weiß -

so zurückgeben Objekt und Guss ist die logische Alternative

jedoch eine Art Rückkehr zu beachten, dass, wenn Ihr Entwurf, den Sie in diese misslichen Lage gezwungen hat, kann es sei ein Fehler darin; vielleicht einige weitere Details können Sie uns helfen

Anmerkung helfen: Jon Skeet ist immun gegen alle solche Einschränkungen

+10

Jon Skeet hat auch Umschalttasten und Punkte auf seiner Tastatur. –

+0

@ [Robert Harvey]: Jon Skeet braucht keine Tastatur; er hat eine direkte neurale Schnittstelle mit freundlicher Genehmigung von Google UK .... und wenn E e Cummings Sie stört, fühlen Sie sich frei zu bearbeiten. ;-) –

0

Was dazu:

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

Sie dies tun wollen?

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

Wenn Sie diese Methode aufrufen, können Sie tun:

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

es eine Menge von "links (str, 1) < 'x'" aber auch andere Zeiten sind es einfach ist abc = left (str, 3)

In diesem speziellen Fall könnten Sie einfach eine Zeichenfolge aus einem Zeichen zurückgeben. Der Vergleich von Strings funktioniert in ihrer lexikografischen Reihenfolge, so dass hier keine speziellen Zeichen verwendet werden müssen (es sei denn, der ursprüngliche Autor hat den Polymorphismus verwendet, um die Zeichen anders als Strings zu behandeln. In diesem Fall haben Sie meine Sympathien).

0

Enriquev,

Es gibt keine Möglichkeit, die Recht ohne Änderung der Syntax von VBA zu implementieren. Sie könnten angeben, welcher Rückgabetyp Sie wollten, aber im Wesentlichen werfen ...

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

ich wirklich glaube nicht, dass dies Ihr Problem löst.

Ist es möglich, eine Regex-Ersetzung aller einzelnen Zeichen, die von einfachen Anführungszeichen umgeben sind, auszuführen? Dadurch werden die Zeichen zu Zeichenketten, und Ihre Vergleichsoperatoren können arbeiten.

0

sollte diese Arbeit:

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