Wenn das irgendwo steht ist das eindeutig falsch.
LINQ returnt bei anonymen Rückgaben (wie zb Select(x=> new { .. } ) ) nämlich dynamic.
Das stimmt nicht. Der Typ ist ja auch nicht dynamisch, sondern trotzdem statisch. Im Intellisense wird er mit a' Bezeichnet und zugreifen kann man mit var und bekommt funktionierendes IntelliSense.
var temp = new
{
Name = "Mustermann",
Vorname = "Max"
};
var result = from x in Enumerable.Range(1, 100)
select new
{
Temp = 1
};
var n = result.First();
Listen können nun mit dem Listensyntax erstellt werden, wenn die Add Methode eine Erweiterungsmethode ist
Die Möglichkeit, Listen mit der Listensyntax zu initialisieren, ist m.E. nicht neu. Ich denke, das geht schon jetzt. Und ich denke, dass es reicht, wenn eine passende Add-Methode vorhanden ist, egal ob direkt in der Klasse oder als Erweiterungsmethode.
Habe es gerade ausprobiert. Folgendes kompiliert nur mit dem neuen Roslyn Kompiler und gibt einen Compilerfehler mit dem alten:
public class MyClass : IEnumerable<string>
{
static void Main(string[] args)
{
var temp = new MyClass { "a", "b" };
}
public IEnumerator<string> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
public static class Extension
{
public static void Add(this MyClass cls, string test) { }
}
Fehler
Program.cs(14,37): error CS0117: 'MyClass' enthält keine Definition für
'Add'.
Program.cs(14,41): error CS0117: 'MyClass' enthält keine Definition für
'Add'.
Automatische initialisierung von Eigenschaften finde ich generell ziemlich gut, allerdings sieht die Syntax "falsch" aus. Ich finde ein = nach einer schließenden Klammer ziemlich seltsam.
An die Syntax für Primärkonstruktoren kann man sich gewöhnen, auch wenn man da ganz grausige Dinge tun kann:
public class Foo(public string bar){ }
ist äquivalent zu:
public clas Foo
{
public string bar;
public Foo(string bar)
{
this.bar = bar;
}
}
Usings für Statische Member find ich auch ziemlich grausig. Werde ich auf jedenfall nicht benutzen.
Und das out Feature ist eigentlich nur ein Spezialfall vom Eigentlichen Feature.
Zuweisungen können nun aus Ausdrücke verwendet werden.
Folgendes geht jetzt:
int i = int j = 5;
Foo(int x = 6);
//usw
try catch mit Conditions ist auf den ersten blick überflüssig, aber gar nicht so verkehrt. Denn die Conditions verfälschen nicht den Call Stack.
Binärschreibweise ist praktisch. Es wird auch noch über etwas anderes debatiert. Und zwar über das Gruppieren in diesen literalen:
0x0101_1010
So kann man Zusammengehörige Flags gruppieren. Man kann beliebig viele unterstriche benutzen.
Weitere Features:
Listen können nun mit dem Listensyntax erstellt werden, wenn die Add Methode eine Erweiterungsmethode ist:
MyClass x = new MyClass(){"a", "b", "c"}; // wenn es eine Erweitungsmethode für Add gibt
Dictionaries können übersichtlicher angelegt werden
var dic = new Dictionary<string, string>
{
["x1"] = "y",
["x2"] = "y",
["x3"] = "y"
};
Und das schrecklichste:
var dic = new Dictionary<string, string>
{
$x1 = "y",
$x2 = "y",
$x3 = "y"
};
Das ist auch völlig äquivalent zum verherigen.
Ganz schlimm:
var dic = new Dictionary<string,string>{...};
string result = dic.$x1;
//Ist äquivalent zu
string result = dic["x1"];
Interessanterweise gab es auf der Build eine Demo dazu. Man hat eine sehr alte VB6 Anwendung weitesgehend Automatisch nach winforms C# und von dort in eine Store App und in eine Webanwendung umwandeln können. Ich glaube das war in der Keynote gestern, bin mir aber nicht ganz sicher. Scheint mit einem Drittanbietertool gemacht worden sein was wohl bald? rauskommt.
Auch sehr interessant finde ich den vorgestellten neuen JIT Compiler, welcher ja nicht nur schneller ist als der alte, sondern auch die Türe zur utilisierung aufwendiger CPU Befehle öffnet, z.B. zu SIMD. Die gezeigten Beispiele (die man sich im übrigen auch selbst runterladen und testen kann) sind wirklich beeindruckend.
Das sieht so aus als würde die Methode sehr oft aufgerufen werden für viele Elemente. Du kannst das parallelisieren und die Elemente parallel abarbeiten, wenn du performance Probleme hast. Trotzdem hab ich noch 2 Anmerkungen zu deinem Beispiel Code.
Diese ganzen If Abfragen lassen sich sehr schön kurz als ein boolscher Ausdruck schreiben. Etwa so:
private bool Filtered(string s)
{
return s.StartsWith("Closed session for ")
|| s.StartsWith("Opened session for ")
|| s.StartsWith("Starting replication with server ")
|| s.StartsWith("Finished replication with server ")
|| (s.StartsWith("Router: Transferred ") && s.Contains(" messages to "));
}
Das machts etwas lesbarer. Dann noch eine Sache. Ich würde mir überlegen die Methode umzubennenen. Mir z.B. ist nicht klar was sie tut. Ist sie true, wenn ein Element in der Auflistung sein soll, oder ist sie true wenn nicht, also filtert sie raus?
So werden interfaces Explizit implementiert. Die Properties tauchen dann nur auf wenn auch das interface gecastet wird. Das ist z.B. auch wichtig bei IEnumerable. Es gibt die interfaces IEnumerator und IEnumerator<T>. Beide fordern ein Property Current. Bei dem generischen Typ ist es vom Typ T. Bei IEnumerable vom Typ object. Das beißt sich also. Also musst du eine Implementierung explizit angeben. Sieht dann also so aus:
public T Current {get{...}}
public object IEnumerator.Current {get{...}}
Ich würde bei diesen Anforderungen manuell arbeiten. Mit der MemoryMappedFile-Klasse. Dann kann sich das Betriebssystem darum kümmern was im Ram und was auf der Platte liegt. Zum Anzeigen müsstest du dann eine kleinere Kopie für den Ram erzeugen. Das sollte aber halb so wild sein
Mit NAudio ist das ganz einfach. Habe das erst vor kurzen gebraucht:
NAudio.CoreAudioApi.MMDeviceEnumerator e = new NAudio.CoreAudioApi.MMDeviceEnumerator();
var endpoint = e.GetDefaultAudioEndpoint(NAudio.CoreAudioApi.DataFlow.Render, NAudio.CoreAudioApi.Role.Multimedia);
Dann kann mit endpoint.AudioMeterInformation.MasterPeakValue die aktuelle Lautstärke des gerade ausgegebenen Audios abgefragt werden.
Edit: Ansonsten hat der endpoint noch ein Haufen weiterer Properties und Funktionen mit denen man auch an die Rohdaten kommen müsste
var runTask = new Task( async () => { var t = await SomelongRunningMethod();
System.Console.WriteLine("Lambda has finished.");
});
Du übergibst dem Task Konstruktor eine Action, also gibt der lambda Ausdruck ein void zurück. Also verhällt sich das ganze nach "Fire and Forget" und returned direkt an dem await un der Task ist damit beendet. Der Task weiss nicht das die Methode intern noch weiterläuft
Ich habe solche dynamischen Reaktionen auf einen oder mehrere Parameter per Attribute gelöst. Ich hatte eine solche Struktur vorgegeben:
Rechte sind hirarchisch angeordnet.
Hauptbereich.Unterbereich.Unterunterbereich
Wenn ein Nutzer oder Gruppe das Recht Hauptbereich.Unterbereich.* hat, hat er alle Rechte in dem Bereich. Ein "*" beduetet so, dass ein Nutzer alle Rechte hat.
Ein Beispiel, was ich nun umsetzen wollte: Servers.[server].Edit. Zum Beispiel für einen Administrationsbereich. Es gibt ann z.B. einen Benutzeraccount, oder eine Gruppe, welche Einstellungen eines Servers ändern darf, aber nicht die anderer. [server] entspricht dann einem Parameter der Action.
Mein Attribut dafür sieht dann so aus:
public class PermissionAttribute : FilterAttribute, IAuthorizationFilter
{
public string[] Pattern { get; set; }
static Regex _regex = new Regex("\\[(?<value>[^.]+)\\]", RegexOptions.Compiled);
public PermissionAttribute(params string[] pattern)
{
Pattern = pattern;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// ... Weiterleitung auf Login Seite?
}
var pattern = from p in Pattern
select _regex.Replace(p, match => GetValue(filterContext, match.Groups["value"].Value));
using (var repository = new PermissionRepository ())
{
if (!pattern.Any(a => repository.CheckPermission(filterContext.HttpContext.User.Identity.Name, a)))
{
//Keine Rechte...
}
}
}
private static string GetValue(AuthorizationContext filterContext, string parameter)
{
var value = filterContext.Controller.ValueProvider.GetValue(parameter);
if (value != null) return value.AttemptedValue;
return (string)filterContext.ActionDescriptor.GetParameters ().First(a => a.ParameterName == parameter).DefaultValue;
}
}
Es ist etwas aufwendig, wenn man auch noch Defaultparameter abdecken will, sonst wär es etwas einfacher.
Das macht es jetzt aber ziemlich einfach und übersichtlich dann die Rechte an die Actions oder Controller zu vergeben:
[Permission("Servers.[server].Edit", "Oder.ein.anders.Recht")]
public async Task<ActionResult> Index(int server)
{
//...
}
Mir ist gerade noch eine Idee gekommen. Und zwar kann ein Ordner auch mehrere NTFS Streams umfassen, in dem man soetwas speichern kann. Dann wärst du aber an NTFS gebunden, und solche Informationen überleben auch keinen Transfer über z.B. FTP.
Du kannst Visual Studio 2010 ohne Probleme verwenden. Projekte die in einer der beiden Versionen erstellt wurden, lassen sich sogar in der anderen öffnen. Es kann natürlich sein, dass mal ein Knopf in Visual Studio 2010 an einer anderen Stelle zu finden ist als in 2012, das sollte aber eher die Ausnahme sein. Für einen Anfänger würde allerdings auch die kostenlose Express Version von Visual Studio ausreichen (Bald kommt sogar Version 2013 heraus). Visual Studio 2010 ist aber keinesfalls veraltet.
Was vielleicht noch funktionieren könnte (habe es selbst nie benutzt) ist Process.WaitForInputIdle(), ansonsten wird es, wie herbivore gesagt hat, bei fremden Prozessen echt schwierig
Edit: Habe den Startbeitrag nicht gründlich genug gelesen
Mir ist kein Verfahren bekannt, mitdem eine nicht abhörbare verschlüsselte Verbindung aufgebaut werden kann, ohne eine vertrauenswürdige Stelle, oder ein entsprechendes Zertifikat, mitdem man einen Public Key verifiziert. Ansonsten kann man immer eine Man in the Middle Attacke ausführen, indem sich der Man in the Middle für den "Server" (Ich nenne die Seite mit dem Private Key Server, und die andere Client) als Client ausgibt, und für den Client gibt er sich als Server aus. So hat der Man in the Middle sein eigenes Public Key / Private Key Paar. Um das zu verhindern muss der Client eine Möglichkeit haben den Key, der bei ihm ankommt zu Verifizieren, z.B. indem über eine vertrauenswürdige Stelle überprüft wird, ob der Key auch wirklich vom Absender stammt, oder indem die Vertrauenswürdige Stelle ein Zertifikat erstellt, welches dann genutzt wird, und der Client kann dieses mit dem Zertifikat der Vertrauenswürdigen Stelle überprüfen, ob der Key, der bei ihm ankommt auch wirklich von der Vertrauenswürdigen Stelle ausgestellt wurde, und somit die Angaben darin auch korrekt sind.
Eine andere Möglichkeit wäre es natürlich die Keys einmalig über ein anderes Transportmedium auszutauschen (z.B. das übertragen über einen USB Stick), um somit die Unsichere Schlüsselaushandlung zu umgehen.
Ich hoffe ich habe mich einigermaßen Verständlich ausgedrückt :)