List<uint> l1 = new List<uint> { 1, 2, 3 };
var l2 = l1.Cast<int>().ToList();
Das wirft
Fehler
System.InvalidCastException: "Unable to cast object of type 'System.UInt32' to type 'System.Int32'."
Nun ja, das lässt sich ja einfach mit
var l2 = l1.Select(i => (int)i).ToList();
ersetzen, kein Problem.
Aber irgenwie hat mir das keine Ruhe gelassen, IEnumerable<T> Cast<T> ist folgendermaßen implementiert:
public static IEnumerable<T> Cast<T>(this IEnumerable source)
{
foreach (object o in source)
yield return (T)o;
}
Das Problem ist, dass der Wert in ein object gesteckt wird, dieser Code wirft die gleiche Exception:
uint i = 42;
object o = i;
int j = (int)o;
Erst dachte ich, Werttypen können nicht aus einem object zurück gecastet werden, aber folgerndes funktioniert:
int i = 42;
object o = i;
int j = (int)o;
Warum können objects, mit einem Werttypen, nicht in einen anderen Werttypen gecastet werden? Vor allem da ja in der Exception die korrekten Typen genannt werden, also warum kann er den Cast nicht ausführen?
Bringt ihm nix, SelectedItem wird erst aktualisiert hat nachdem das Item angeklickt wurde.
Ich denke du wirst selbst berechnen müssen über welchen Item der Mauszeiger ist.
Du kannst das MouseMove Event abonieren, in den MouseEventArgs bekommst du die Koordinaten und dann kannst du per DropDownHeight und der Anzahl der Items berechnen über welchen Item der Zeiger sich befindet.
Nein, das geht definitiv nicht.
Max. an die Metatdaten (Name und auf welchem Index sie liegen) kommt man ran. Mir sind ach keine anderen Libs bekannt die das können (mit Mono.Ceici z.B. gehts auch nicht).l
Das Problem mit dem Überlauf besteht weiterhin.
Int32 und int sind, wie schon angemerkt der gleiche Datentyp.
Das Problem lässt sich leider nicht (so einfach) lösen, da die verwendeten Windowsfunktionen nur 32bit Werte als Paramter haben und es keine 64bit Versionen gibt.
Nach ewiger Zeit hab ich mal wieder daran gesetzt und das Projekt an den aktuellen Stand des originals gebracht und endlich werden auch 64bit unterstützt.
Enschränkungen:
- Nur 32bit oder 64bit möglich (Aufruf aus "MixedMode" (noch) nicht möglich)
- Kein laden von resourcen aus der nativen DLL
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( ... );
}
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.
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?
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)
{
//...
}
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));
}
Kennt das jemand?
Man hat ein neues Projekt und benötigt eine native Bibliothek, freut sich schon mal das es einen .net Wrapper gibt und dann bekommt man sinngemäß sowas serviert:
int err = FancyMethod(int foo, string bar);
if (err != 0)
// Fehlerbehandlung hier
Nicht zu vergessen das der ganze Wrapper nur aus statischen Methoden besteht.
Warum macht jemand sowas?
Da kann ich gleich die DLL mit DllImport selber laden, mit Objektorientierung hat das doch nix zu tun.
OK, immerhin muss ich mich nicht mit dem ganzen Marshalling herumschlagen, aber trotzdem nervt mich sowas immer wieder.
Ich würde sowas nicht mit dem PC steuern, sondern einen Arduino dafür einspannen. Gibt eine MIDI Lib dafür und ein Relais ist auch schnell angeschlossen.
Für ein Midi-Interface braucht es gerade einmal zwei Widerstände an Arduino.
Zu den MIDI Befehlen, das Stichwort ist MMC (MIDI Machine Control): MIDI Machine Control
wenn es wirklich C++ ist, also Objektorientiert, dann ist es mit einfachem PInvoke (= DLL-Import) nicht getan, da musst du dann mit Implicit PInvoke ran, d.H. du musst erst einen Wrapper in Managed C++ schreiben.
So ein Wrapper kann allerdings recht aufwendig werden, gerade bei einem großen Toolkit wie dem JT Open Toolkit, wäre so ein Wrapper allein ein recht großes Projekt.
Ich hab so was mal für eine recht kleine Library gemacht, alleine die Konvertierung der X Stringtypen hat mir einige Graue Haare gekostet. ;)
In der Regel macht man sowas mit einem eigenen Event, welches vom Aufrufer abonniert wird.
Und wenn man dann ohnehin ein eigenes Event hat - ist es zudem recht intelligent diesem auch ein Property in Form des Objekts, welches der Aufrufer gerne hätte mitzugeben.
An events hatte ich zu aller erst gedacht, und wollte es ganz modern mit async/await lösen und hab aber überhaupt nichts zu events in Verbindung zu async/await gefunden.
Zitat von Taipi88
a) Ich würde i.d.R. nicht versuchen ein einziges Objekt immer wieder zu benutzen - du weisst doch gar nicht, ob das alte und die alten Werte gerade noch in Arbeit sind und was damit gerade geschieht - ich fände es z.B. echt kacke, wenn gerade einzelne Eigenschaften des objects irgendwo geloggt werden - und dann dein Task mitten im Loggen anfängt Sachen zu ändern, womit im Endeffekt Mist geloggt wird
Ja guter Punkt, werd ich so umsetzen.
Zitat von Taipi88
b) Primäres Augenmerk wird somit dabei liegen, dass die UI nicht abschmiert // Control.Invoke bzw. WPF-Gegenstück dazu
c) Folgendes würde ich mir zu Multithreading anschauen: http://www.albahari.com/threading/
Ich dachte mit Einführung von Tasks sollte man Threads i.d.R. nicht mehr benutzen.
Besonders gefällt mir das das ganze ohne Control.Invoke und Co. auskommt.
In Verbindung TaskCreationOptions.LongRunning, sollte das perfekt für meinen Anwendungszweck sein.
wie kann ich am besten während eines laufenden Tasks Daten an den Aufrufer zurückgeben bzw. synchronisieren ohne das es zu Race conditions oder Dead locks kommt?
Mein Ansatz bisher:
class AsyncPolling
{
public object Obj { get; private set; }
public async Task PollAsync(IProgress<bool> progress, CancellationToken ct)
{
await Task.Run(() =>
{
while (true)
{
// Process some data...
if (data_has_changed)
{
Obj = ...
progress.Report(true);
}
ct.ThrowIfCancellationRequested();
}
}, ct);
}
}
In der schleife frage ich ständig ein Gerät ab (per Polling, geht leider nicht anders), das die Zustände in _o speichert. _o ist relativ komplex. Die Daten sollen dann weiterverarbeitet bzw. angezeigt werden.
Ich würde ungern Obj über IProgess<T> schleusen, am liebsten wäre mir wenn ich darüber dem Aufrufer nur mitteile das neue Daten vorliegen und der die sich die aus dem Property holt.
Muss ich das Property noch locken oder ist das bei async .. await nicht nötig?
Oder ist der Ansatz zu naiv und ich bin komplett auf dem Holzweg?
Obfuscatoren nutzen das z.B. im dem sie dann die Variablennamen in irgendwelche exotischen (nicht druckbare) Zeichen umwandeln um die Rückverfolgbarkeit des Codes im Reflector zu erschweren. Ich glaub der .net Reflector stürzt sogar bei bestimmten Zeichen ab. Zumindest ältere Versionen.
Eigentlich OT:
Sinn macht es aber z.B. bei Programmen die als "Systemerweiterung" angesehen werden können.
Ich benutze eine erweiterte Taskleiste für den zweiten Monitor und das bringt im SystemMenu einige sinnvolle Einträge unter. z.B. Fenster auf den anderen Monitor verschieben.
Einfach in der HTML code Ansicht rechtsklick auf das element -> "XPath kopieren".
Beim darüberfahren zeigt er dir den Xpath schon als hover an.
Klappt auch mit xml wunderbar.
Ach ja: Wir reden von dem externen Plugin Firebug, NICHT von den eingebauten "Entwicklertools", die bieten die Funktion nicht.
die equal() Methode verglicht NICHT ob es sich um das gleiche Bitmap handelt sondern ob die beide Objekte(!) identisch sind. Siehe: Object.Equals-Methode (Object)
Um wirklich zu überprüfen ob es sind um die selben Bilder handelt musst du das selbt implemtieren. Das .net Framwork stellt hierzu glaube ich nichts bereit.
Zuerst hab ich mit dem originalen C-Programm von David H. Bailey (BBP Code Directory) mir die entsprechende HEX Postion berechnen lassen, dann mit Hilfe eines Online-Converters zuerst nach Binär und dann nach ASCII Konvertiert.
Zitat von zommi
Ein einzelnes MD5-Hashing sieht bei mir so aus:
String -> ASCII Byte-Array -> MD5 Byte-Array -> String mit großbuchstaben HEX-Werten (ohne Bindestriche oder so)
8o
Danke ich hatte den String in Kleinbuchstaben. Hätte auch gut selber drauf kommen können/müssen. Kopf->Tisch
Hier der Code:
Ist genau wie die "manuelle" Vorgehensweise. Nicht sonderlich elegant (geht sicher auch ohne das HEX/Binär String konvertiere) und mehr als 50 Zeilen aber es funktioniert!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace BBP
{
class Program
{
static void Main(string[] args)
{
const string testHash = "182C3950020DBE5969AF859ADF93BBD4";
double pid, s1, s2, s3, s4;
// Vorherige "Hex-Nachkommastelle" zur gesuchten Position finden
int id = 787471 / 4; // 196867;
// Hex-Nachkommastellen berechnen
s1 = BBP.Series(1, id);
s2 = BBP.Series(4, id);
s3 = BBP.Series(5, id);
s4 = BBP.Series(6, id);
pid = 4 * s1 - 2 * s2 - s3 - s4;
pid = pid - (int)pid + 1;
string hex = BBP.Ihex(pid);
// In Binärstring umwandeln und Bit-Position korrigieren
string bin = HexToBinString(hex).Substring(787471 % 4 - 1);
// In Bytes umwandeln
byte[] bytes = BinStringToByte(bin);
// und ASCII decodieren
string word = Encoding.ASCII.GetString(bytes, 0, 3);
Console.WriteLine("Wort: {0}", word);
// Testen
MD5 md5 = MD5.Create();
string hash = word;
for (int i = 0; i < 1000000; i++)
hash = GetMd5Hash(md5, hash);
Console.WriteLine("Hash: {0}", hash);
Console.WriteLine("Test-Hash: {0}", testHash);
Console.WriteLine("Hashes are{0} equal!", hash != testHash ? " not" : "");
Console.ReadLine();
}
// Hilfsmethoden
static string GetMd5Hash(MD5 md5Hash, string input)
{
byte[] data = md5Hash.ComputeHash(Encoding.ASCII.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
sBuilder.Append(data[i].ToString("X2"));
return sBuilder.ToString();
}
static byte[] BinStringToByte(string binstring)
{
var bytesAsStrings =
binstring.Select((c, i) => new { Char = c, Index = i })
.GroupBy(x => x.Index / 8)
.Select(g => new string(g.Select(x => x.Char).ToArray()));
return bytesAsStrings.Select(s => Convert.ToByte(s, 2)).ToArray();
}
static string HexToBinString(string hexstring)
{
return String.Join(String.Empty,
hexstring.Select(
c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0')));
}
}
/// <summary>
/// "Quick and dirty" Port des orginalen C Codes von David H. Bailey
/// </summary>
static class BBP
{
public static string Ihex(double x)
{
int i;
double y;
StringBuilder sb = new StringBuilder();
string hx = "0123456789ABCDEF";
y = Math.Abs(x);
for (i = 0; i < 16; i++)
{
y = 16 * (y - Math.Floor(y));
sb.Append(hx[(int)y]);
}
return sb.ToString();
}
/// <summary>
/// This routine evaluates the series sum_k 16^(id-k)/(8*k+m)
/// using the modular exponentiation technique
/// </summary>
/// <param name="m"></param>
/// <param name="id"></param>
/// <returns></returns>
public static double Series(int m, int id)
{
int k;
double ak, p, s, t;
double eps = 1e-17;
s = 0;
/* Sum the series up to id. */
for (k = 0; k < id; k++)
{
ak = 8 * k + m;
p = id - k;
t = Expm(p, ak);
s = s + t / ak;
s = s - (int)s;
}
/* Compute a few terms where k ≥ id. */
for (k = id; k ≤ id + 100; k++)
{
ak = 8 * k + m;
t = Math.Pow(16, (double)(id - k)) / ak;
if (t < eps) break;
s = s + t;
s = s - (int)s;
}
return s;
}
/// <summary>
/// expm = 16^p mod ak. This routine uses the left-to-right binary
/// exponentiation scheme
/// </summary>
/// <param name="p"></param>
/// <param name="ak"></param>
/// <returns></returns>
private static double Expm(double p, double ak)
{
int i, j;
double p1, pt, r;
int ntp = 25;
double[] tp = new double[ntp];
int tp1 = 0;
/* If this is the first call to expm, fill the power of two table tp. */
if (tp1 == 0)
{
tp1 = 1;
tp[0] = 1;
for (i = 1; i < ntp; i++)
tp[i] = 2 * tp[i - 1];
}
if (ak == 1)
return 0;
/* Find the greatest power of two less than or equal to p. */
for (i = 0; i < ntp; i++) if (tp[i] > p) break;
pt = tp[i - 1];
p1 = p;
r = 1;
/* Perform binary exponentiation algorithm modulo ak. */
for (j = 1; j ≤ i; j++)
{
if (p1 ≥ pt)
{
r = 16 * r;
r = r - (int)(r / ak) * ak;
p1 = p1 - pt;
}
pt = 0.5 * pt;
if (pt ≥ 1)
{
r = r * r;
r = r - (int)(r / ak) * ak;
}
}
return r;
}
}
}
Die Felder müssen mit new initialisiert werden, auch wenn es innere Klassen sind.
Das kannst du entweder gleich bei der defintion machen:
public SourceInfo Ursprungsbild = new SourceInfo();
public ProcessedInfo Arbeitskopie = new ProcessedInfo();
oder du initialisierst sie in einem Konstruktor:
public TabPicture()
{
this.Ursprungsbild = new SourceInfo();
this.Arbeitskopie = new ProcessedInfo();
}
Aber ich denke du hast OOP noch nicht richtig verstanden . Daher der Hinweis auf [Hinweis] Wie poste ich richtig? Punkt 1.1 1.1.1
Warum hast du zwei Klassen die exakt gleich aufgebaut sind SourceInfo und ProcessedInfo?
Du brauchst nur eine Klasse:
z.B:
public ImageInfo SourceInfo = new ImageInfo();
public ImageInfo ProcessedInfo = new ImageInfo();
public class ImageInfo
{
public Image Bild { get; set; }
public int Dateigröße { get; set; }
public int Breite { get; set; }
public int Höhe { get; set; }
}