| 

.NET C# Java Javascript Exception

8
Hallo liebe CK-Com,

hier mal eine kleine Frage, wo ich wirklich hoffe, eine Lösung zu finden.
Wer sich mit C# ein bisschen besser auskennt, kennt auch typeof(Object);
Was ich mich hierbei Frage ist, ob man das mit dem Parameter "nachbilden" könnte bei einer eigenen Funktion...
mein Ziel ist so ein Aufruf wie:
MyClass.MyMethod(AnyClass);
ich möchte also nicht eine Instanz eines Objektes übergeben müssen sondern einfach nur die Klasse selbst.

Geht das überhaupt?
Und wenn ja: wie?

//EDIT
da gefragt wurde, was genau das Ziel ist:
ClassInheritenceChecker.classImplementsInterface(AnyClass, AnyInterface);

//Genaueres Beispiel
public interface IModule{/*...*/}
public class FileBrowserModule : IModule {/*...*/}

public partial class frmMain : Form
{
private loadModules()
{
if(ClassInheritenceChecker.classImplementsInterface(FileBrowserModule, IModule)
{
//Do Something...
}
}
}


so far
Karill Endusa
News:
01.02.2012
Karill Endusa 1,5k 1 9
6 Antworten
5
Wie wär es mit einer Lösung über Generics:
public static class ClassInheritenceChecker
{
public static bool ClassImplementsInterface<TClass, TInterface>()
where TClass : class
{
return typeof(TInterface).IsAssignableFrom(typeof(TClass));
}
}

der Aufruf:
if (ClassInheritenceChecker.ClassImplementsInterface<FileBrowserModule, IModule>())
{
//Do Something...
}
01.02.2012
PinBack 687 1 8
+1
Perfekt
Genau so find ich es gut, man versteht es, es ist das wonach ich gesucht habe... schon schade, dass man das über <TClass, TInterface>() regen muss und es nicht direkt als "Parameter" (TClass, TInterface) geht, aber so ist das echt super!
Karill Endusa 01.02.2012
3
Hi Karill,

ich kann folgende Idee beisteuern:

Generische ExtensionMethod für System.Type
// ExtensionMethod
public static bool ImplementsInterface<TInterface>(this Type t)
where TInterface : class
{
//..
}

// Aufruf
if(typeof(FileBrowserModule).ImplementsInterface<IModule>())
{
// ...
}

Noch ne Idee:
public static class Class<T> 
{
public static bool ImplementsInterface<TInterface>() { /*...*/ }
}

bool result = Class<FileBrowserModule>.ImplementsInterface<IModule>();


Gruß
Florian
01.02.2012
ffordermaier 8,4k 3 9
ganz nett, insbesondere da es auch noch eine Extensionmethod ist... leider brauche ich dafür immer noch ein Type-Objekt.
Trotzalledem +1 und danke für die Mühe.
Karill Endusa 01.02.2012
Bitte, gerne. Hatte spontan noch ne Idee, siehe editierte Antwort.
ffordermaier 01.02.2012
wow... könnte man mehrere Antworten akzeptieren, wäre diese wegen deiner zweiten Lösung noch dabei... die is sogar noch "genialer"...
Danke für diese Ergänzung, das wird wohl der Weg sein, den ich nun nehmen werde!
Karill Endusa 01.02.2012
immer wieder gerne. Wenn Dich der "Haken" den Matthias angesprochen hat, tatsächlich aus der Bahn werfen sollte (ich gehe davon aus, dass Dir nur das Interface zur Compile-Zeit bekannt ist), lass es uns wissen. Aus all den Antworten hier lässt sich sicher eine adäquate Lösung konstruieren.
ffordermaier 01.02.2012
Genau das ist der Punkt: Zur Laufzeit selbst ist nur das Interface bekannt.
In einer meiner vielen Kommentare steht, wofür ich das benutzen wollte:
Es geht in erster Linie um ein Pluginsystem, wobei das Plugin (ergo die Klasse) um es als solches zu identifizieren ein oder mehrere Interfaces implementieren muss (IPlugin, IModule, IModuleMetadata).
Insofern stimmt es, dass die Klasse selbst nicht bekannt sein wird zur Compilezeit.
Karill Endusa 01.02.2012
Dann bin ich wieder bei meinem ersten Vorschlag. Du hast dann wahrscheinlich ein Array von Type-Objekten, in denen Du nach Plugins via Interface suchen willst (via Reflection von einem Assembly-Objekt abgerufen).

Type someType = lotOfTypes[0];
if(someType.ImplementsInterface<IModule>())

BTW: Schau Dir mal MEF an. (http://msdn.microsoft.com/de-de/library/ee332203.aspx)
ffordermaier 01.02.2012
Danke für den Link auf MEF, aber ist für mich nicht nutzbar.
Bedingung für das Projekt ist unter anderem .NET 2.0 bevorzugt, maximal 3.5 ...
Karill Endusa 01.02.2012
3
Von mir auch noch mal eine Idee als extension Method , auch wenn die Frage schon als Beantwortet getaggt ist ^^

public static bool ImplementsType(this object testObject, Type check)
{
if (check.IsInterface)
{
return testObject.GetType().GetInterfaces().Contains(check);
}

return testObject.GetType() == check || testObject.GetType().IsSubclassOf(check);
}


Kann dann für jeden Typ Benutzt werden...

public interface ISuperCoolMath
{
bool IsEndOfUniverse();
}

public class Shape { }
public class Circle : Shape { }

public class Triangle : Shape, ISuperCoolMath
{
public bool IsEndOfUniverse()
{
return true;
}
}


static void Main(string[] args)
{
Int32 i = 0;

Console.WriteLine("Result: {0}", i.ImplementsType(typeof(int)));
Console.WriteLine("Result: {0}", i.ImplementsType(i.GetType()));
Console.WriteLine("Result: {0}", i.ImplementsType("".GetType()));
Console.WriteLine("--------------");
var c = new Circle();
Console.WriteLine("Result: {0}", c.ImplementsType(typeof(Shape)));
Console.WriteLine("Result: {0}", c.ImplementsType(typeof(ISuperCoolMath)));
Console.WriteLine("--------------");
var t = new Triangle();
Console.WriteLine("Result: {0}", t.ImplementsType(typeof(Shape)));
Console.WriteLine("Result: {0}", t.ImplementsType(typeof(ISuperCoolMath)));


Console.ReadKey();
}


Ausgabe :

Result: True
Result: True
Result: False
--------------
Result: True
Result: False
--------------
Result: True
Result: True


um das typeof / GetType() kommst du bei meiner Idee aber auch nicht drumherum :)

Grüße
01.02.2012
Nicolai Schönberg 2,4k 2 9
1
Auch ganz nett... ich brauch das zwar nur für Interfaces, aber deine Variante hat auch Stil... ich habs mir zumindest mal abgespeichert, kann ich sicher in der Form auch mal brauchen.
Karill Endusa 01.02.2012
2
Die Methode müsste dann so deklariert sein:
public MyClass
{
public void MyMethod(Type type)
{
//Tu was damit
}
}

Der Aufruf würde so aussehen:
MyClass instance = new MyClass();
object other = new OtherObject();
instance.MyMethod(typeof(other);
//alternativ:
instance.MyMethod(Type.GetType("System.object"));
01.02.2012
carlptr 777 1 8
carlptr 777 1 8
ah schade, genau das Erstellen einer Instanz von OtherObject wollte ich vermeiden können.
Das Erstellen einer Instanz von MyClass kann ich ja verhindern, indem ich die Methode statisch mache...
Karill Endusa 01.02.2012
Du kannst den Type auch ohne Object, mit Type.GetType ermitteln. Hab das mal ergänzt.
carlptr 01.02.2012
genausogut könnte ich auch instance.MyMethod(typeof(OtherObject)); schreiben, also ebenfalls ohne instanz des OtherObject, aber auch darauf würde ich ja gerne verzichten.
Wenn typeof() das kann, wieso kann ich als Entwickler das dann nicht?
Karill Endusa 01.02.2012
Mir erschließt sich jetzt leider nicht, worauf du hinauswillst?
carlptr 01.02.2012
tipp doch einfach mal typeof(AnyClass) in einem Programm ein... da kann man schreiben typeof(TextBox) oder typeof(Int32) oder oder oder...
so will ich das auch machen können, nur das meine Methode/Funktion nunmal nicht typeof heißen soll sondern irgendwie anders.
Mein Ziel wäre dann ein Aufruf ala. myMethod(Boolean) oder myMethod(Int16) oder eben irgendein anderer Objekttyp als Parameter

jetzt verständlich? :)
Karill Endusa 01.02.2012
Er will vermutlich weder den typeof Operator noch die GetType Methode verwenden, sondern einfach nur den Namen der Klasse übergeben. Wäre interessant zu wissen warum, dann könnte man eine Alternative vorschlagen.
me 01.02.2012
jo me hat recht

Ziel ist (vom Namen her) folgende Methode:
ClassInheritenceChecker.classImplementsInterface(AnyClass, AnyInterface);
Rückgabe ist natürlich bool
klar weiß ich, dass das selbst nur wieder ein Einzeiler ist, aber wenn sich jemand den Code dann so durchliest, ist dieser "Aufruf" allein vom Namen her so verständlich, dass man direkt ohne Kommentar weiß, was an der Stelle passiert.

Da ich an einem Pluginsystem arbeite für eines meiner Projekte, wäre das sehr hilfreich, wenn sich das direkt so umsetzen ließe
Karill Endusa 01.02.2012
habe meine Frage oben mal um ein konkretes Beispiel erweitert
Karill Endusa 01.02.2012
2
Ähm, wie war das mit dem Wald und den Bäumen? Oder ich hab doch noch nicht verstanden, was genau Du willst. Das hier müßte gehen, finde ich - wahlweise mit "typeof" oder generischem Typparameter im Aufruf.

public class  MyClass
{
public static void MyMethod(Type type)
{
//Tu was damit
}

public static void MyMethod<T>()
{
MyMethod(typeof(T));
}
}

MyClass.MyMethod(typeof(string));
MyClass.MyMethod<string>();


Die generische Variante hat den Vorteil, dass sie mit ein paar Zeichen beim Aufruf weniger auskommt und in bestimmten Fällen dank Type-Interferenz der Typparameter auch ganz weggelassen werden kann. Dafür kann bei der anderen Variante der Typ auch noch zur Laufzeit ermittelt werden: MyMethod(typeof(myObject)), muss also nicht zur Compile-Zeit feststehen.
01.02.2012
Matthias Hlawatsch 13,2k 4 9
ohne die Benutzung des typeof() wärs das was ich bräuchte :) der Wald scheint manchmal größer als man eh nicht sehen kann
Karill Endusa 01.02.2012
Was Dich an dem typeof stört, hab ich noch nicht geschnallt, aber wie wäre es, wenn Du stattdessen einen generischen Typparemeter nimmst? Hab meine Antwort entsprechend erweitert.
Matthias Hlawatsch 01.02.2012
Es gibt Leute da draußen, die kennen (erstaunlicherweise) typeof() und .GetType() nicht... denen wollt ich das noch einfacher machen.
Wie an meiner akzeptierten Antwort zu sehen ist, war die Idee mit den Generics das, was mir zusagt.
Für die Änderung gibts +1 (haste wohl grad geändert, als ich die Antwort akzeptiert habe ;))
Karill Endusa 01.02.2012
Danke!
Ja, das hatte sich überschnitten.
Ich hab noch einen letzten Satz ergänzt - die generische Variante hat ihre Vorteile, aber auch einen Haken.
Matthias Hlawatsch 01.02.2012
Ich glaub Haken wird es sein, der mich wieder aus der Bahn werfen wird ;)
Ich danke für diese Zusatzinformation
Karill Endusa 01.02.2012
0
Bezüglich der näheren Beschreibung (Ermittlung der implementierten Schnittstellen) würde ich zum Beispiel den Artikel Implementations of interface through Reflection empfehlen.
Ansonsten vielleicht auch einfach:
if (typeof(FileBrowserModule) is IModule))
{
...
}
01.02.2012
me 1,1k 2 9
Wie ich bereits in einem Kommentar gesagt habe, ist mir wohl bewusst, dass es sich nur um einen einzeiler handelt. Im endeffekt geht es mir darum, gerade diesen Einzeiler einfach nur "schöner/informativer" aussehen zu lassen, sollte sich jemand den Quellcode einmal durchsehen.

Der von dir genannte Artikel hilft auch nicht sonderlich weiter, da ich wie bereits beschrieben an einem Pluginsystem arbeite und die Plugins zur Compilezeit eben auch noch nicht bekannt sind.

Ich denke aber, dass ich mit der "normalen" Methode noch am Besten fahre :)
Karill Endusa 01.02.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH