2013-03-12 7 views
5

Ich habe ein Problem mit Überlademethoden mit unterschiedlichen Einschränkungen, die ausschließlich auftreten, gefunden. Das ist mein Beispiel:Mitglied mit der gleichen Signatur, die bereits mit anderen Typenbeschränkungen definiert wurde

public class A 
{ 
    public void Do<T>() where T : class 
    { 

    } 

    public void Do<T>() where T : struct 
    { 

    } 
} 

Und das kompiliert nicht mit dem folgenden Fehler "Mitglied mit der gleichen Signatur bereits definiert". Ist es möglich, beide Bedingungen auf einmal zu erfüllen, oder ist es nur die Einschränkung des C# -Compilers?

Antwort

8

Es ist nicht eine Einschränkung des Compiler - es ist eine Einschränkung der Sprache (und möglicherweise die CLR als auch, ich bin mir nicht sicher).

Im Grunde sind das kollidierende Überladungen - es ist wie ein Überlastungsversuch nach Rückgabetyp. Es wird nicht unterstützt.

Es ist mögliche Methoden zu erklären, dass diese Anrufe alle Anrufungen verschiedener Methoden kompilieren:

a.Do<int>(); 
a.Do<string>(); 
a.Do<int?>(); 

... aber es geht immer optionale Parameter und/oder Parameter-Arrays, und es ist horrible.

Beachten Sie außerdem, dass Sie zwar nicht durch generische Einschränkungen überlasten können Sie können Überlastung durch die generische „arity“ (die Anzahl der Typ-Parameter):

public void Foo() {} 
public void Foo<T>() {} 
public void Foo<T1, T2>() {} 
+0

Wenigstens hoffe ich, dass es richtig war, zu sagen, dass diese beiden Beschränkungen ausschließen und es ist nur Beschränkung , Recht? :) –

+0

@IlyaChernomordik: Es ist eine Einschränkung, aber eine ziemlich vernünftige IMO. –

+0

Aber was ist falsch daran, dies zuzulassen? Ich muss nur verschiedene Aktionen ausführen, je nachdem, ob es eine Klasse ist (ich kann prüfen, ob es null ist) oder wenn es nur lang ist (dann weiß ich, dass der Wert da ist). Der Ausweg sollte also nur sein, den Methoden, die es zu sein scheint, unterschiedliche Namen zu geben. Ich will den schrecklichen Weg definitiv nicht benutzen :) –

2

Sie können keine Methode, mit varing Überlastung der generische Parameter containts. Für eine gültige Methodenüberladung müssen Sie verschiedene Eingabeparameter für die Methode haben.

1

Beide Methoden sollten den folgenden Namen haben, wenn zusammengestellt:

A.Do``1 

Da die Anzahl der generischen Parameter, geht in den Namen der Methode oder Klasse.

nicht sicher, was Ihre Situation ist, aber Sie können die Verwendung von Reflexion diese Methoden machen müssen nennen:

public class A 
{ 
    public void Do<T>() 
    { 
     if(typeof(T).IsValueType){ 
      // nasty reflection to call DoValueType 
     } 
     else { 
      // nasty reflection to call DoReferenceType 
     } 
    } 
    private void DoReferenceType<T>() where T : class { 

    } 
    private void DoValueType<T>() where T : struct { 

    } 
} 
Verwandte Themen