Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Delegate als Constraints
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 323

Themenstarter:

Delegate als Constraints

beantworten | zitieren | melden

Servus zusammen,

bis jetzt hatte ich in einem Projekt eine Methode die einen Delegaten zurückgibt, mir der folgenden Signatur:
Marshal.GetDelegateForFunctionPointer(), funktioniert genau so.


public Delegate GetDelegate(string foo, Type t)
{ 
//...
}
Benutzt wird sie so:


MyDelegate myDelegate = (MyDelegate)obj.GetDelegate("foo", typeof(MyDelegate );

Was ich nicht sehr hübsch finde, der Cast und das typeof() stören mich irgendwie, für so etwas wurden doch Generics erfunden, aber warum kann ich keine Delegaten als Constraints verwenden?
Dadurch kann ich nicht auf den richtigen Typ casten.

Das ist was ich gerne hätte:


public TDelegate GetDelegate<TDelegate>(string foo) where TDelegate : Delegate
{
     return (TDelegate)GetDelegate(foo, typeof(TDelegate));
}

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4188

beantworten | zitieren | melden

Die unter Compilerfehler CS0702 aufgelisteten Typen sind alles nur Meta-Typen, d.h. direkt kann man davon nicht ableiten und daher auch keinen Constraint damit benutzen.
Du könntest aber (wie unter Anyone know a good workaround for the lack of an enum generic constraint? beschrieben) mittels Runtime-Check den Typ überprüfen (s. Check if an object is a delegate).

Eine andere Möglichkeit wäre die Verwendung von unconstrained-melody, s. dessen Kurz-Doku Generic constraints for enums and delegates (ich weiß aber nicht, ob das wirklich für ein Produktivprojekt geeignet ist?).
private Nachricht | Beiträge des Benutzers
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 323

Themenstarter:

beantworten | zitieren | melden

unconstrained-melody ist schon etwas mit Kanonen auf Spatzen schießen, es geht nur um eine Methode in einem Modul.

Ja danke, der Runtime check geht relativ problemlos mit


if (!typeof(Delegate).IsAssignableFrom(typeof(TDelegate)))
    throw new InvalidOperationException();
aber wie kann ich den Delegaten (ich kann erst hier mit dem konkreten Typ arbeiten, es ist im Endeffekt ein nativer Funktionszeiger, mit Marshal.GetDelegateForFunctionPointer erzeugt) auf den konkreten Typ casten?

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16204

beantworten | zitieren | melden

Hättest Du lust zu beschreiben, was Du damit eigentlich erreichen willst?
Hab das Gefühl, dass es da eine bessere Lösung für das Ziel gibt.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 323

Themenstarter:

beantworten | zitieren | melden

Ich beschäftige mich nach langer Zeit mal wieder mit einem alten Projekt: MemoryModule.net (https://github.com/Scavanger/MemoryModule.net).
Es geht darum eine native DLL aus dem Speicher zu laden, ist ein .net-Port des ursprünglich in C geschriebenen Moduls. (https://github.com/fancycode/MemoryModule)

Also ich bekomme einen Funktionszeiger auf eine native Funktion (der geladenen DLL) und wandle ihn mit Marshal.GetDelegateForFunctionPointer() in einen Delegaten.

Wie gesagt, eine Funktion mit Generics wäre schön, dann wäre die Klasse sehr handlich, der Funktionsaufruf mit dem Cast und typeof wirkt doch recht altbacken.

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers
wcseller
myCSharp.de - Member



Dabei seit:
Beiträge: 191

beantworten | zitieren | melden

Hilft Dir das hier vielleicht weiter?

Marshal.GetDelegateForFunctionPointer<TDelegate>()
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von wcseller am .
private Nachricht | Beiträge des Benutzers
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 323

Themenstarter:

beantworten | zitieren | melden

*Klatsch-ans-Hirn*

Danke, damit geht's natürlich easy.
Man sollte doch öfters mal schauen was die neuen Frameworkversionen so bieten. Das Projekt war noch auf dem alten 3.5er, da gab es die generische Version noch nicht.

Ich hab inzwischen einen "nasty Hack" gefunden wie es auch mit den alten Version funktioniert:


public TDelegate GetDelegate<TDelegate>(string foo) where TDelegate : class
{
     // Runtimeprüfung
     return (TDelegate)(object)Marshal.GetDelegateForFunctionPointer( ... );
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Scavanger am .

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers