IMHO, instead of twisting the interlocutors' brains about the abstruse semantics of event and delegates or asking when writing new IEntity()
legal, you can ask a simpler question - for example, “give an example of unusual behavior or use of the C # language”. Here are some examples that came to mind as possible answers.
Both pairs of statements can be applied to bool variables. The only difference is that single operators do not reduce the number of calculations if the result is obvious:
bool b = false && a(); // a() not called
bool c = false & a(); // a() called
Oddly enough, passing null as an exception causes a NullReferenceException
to be NullReferenceException
:
try {
throw null ;
} catch (NullReferenceException) {
// will be caught!
}
It can be a good idea to bother your colleagues if instead of the typical for for when counting, use while
with an unusual arrow. The syntax is absolutely legal! By the way - I remember here on Habré someone embarrassed ...
public IEnumerable<Foo> Create( int count)
{
while (count --> 0)
yield return new Foo();
}
Can I use the operator ?? for lazy object initialization:
private IList<Person> people;
public IList<Person> People {
get {
return people ??
(people = new List<Person>());
}
}
You can also use an operator to check chains of values:
int err( int ? alpha, int ? beta)
{
return alpha ?? beta ?? -1;
}
Although IMHO for laziness is suitable and AOR. Or Boo :)
Extension methods can be applied not only to specific types but also to interfaces. This allows classes to add behavior without wedging into their inheritance hierarchy:
public static void T DeepCopy<T>
( this ICopyable<T> self)
where T : class , new ()
{
â‹®
}
}
In principle, extensions to interfaces are “behavioral impurities” (behavior mixing). Unlike F #, you can't mix in properties, although if you really wanted to (warning: recommended ), you can write something like this:
static class ExtensionMethods
{
private static Dictionary<WeakReference, object > tags =
new Dictionary<WeakReference, object >();
public static void SetTag( this object obj, object tagValue)
{
Cleanup();
var found = tags.Select(o => o.Key)
.Where(k => ReferenceEquals(obj, k.Target));
if (found.Count() > 0)
{
tags[found.Single()] = tagValue;
}
else
tags[ new WeakReference(obj)] = tagValue;
}
public static T GetTag<T>( this object obj)
{
return (T)tags.Where(o => ReferenceEquals(o.Key.Target, obj)).First().Value;
}
private static void Cleanup()
{
var toRemove = tags.Select(o => o.Key).Where(p => !p.IsAlive);
foreach ( var tr in toRemove)
tags.Remove(tr);
}
}
Sometimes you need to keep the variable name in a string literal. Instead of using a literal directly, you can pass a delegate to a function and pull out the string when parsing the expression. (This makes the code more secure and makes refactoring easier.)
public static string PropertyName<T>
( this object obj, Expression<Func<T>> p)
{
return (p.Body as MemberExpression).Member.Name;
}
You can use this design as follows:
lblName.DataBindings.Add(
PropertyName(() => Name), this , null );
Similar manipulations are possible with methods. And indeed with anything :)
It is possible to do boldly from the try-finally block. At the same time, the compiler caches the return value, and it will be returned only after the execution of the finally block.
try {
a();
return x; // cached
}
finally {
b(); // called before x is returned
}
The IDisposable interface can be used to create blocks, the input and output to which you want to intercept. For example, change the cursor to the time of the operation:
class WaitCursor : IDisposable {
private Cursor oldCursor;
public WaitCursor(Cursor oldCursor) {
this .oldCursor = oldCursor;
SetCursor(Cursor.Wait);
}
public void Dispose() {
SetCursor(oldCursor);
}
}
You can use this construct as follows:
using ( new WaitCursor( this .Cursor))
{
// long operation
}
Although for such constructs you can also use AOR.
public event MyClickHandler Click = delegate {};
The fact that employers are straining their interlocutors with all sorts of delusional tasks like “isolated case” is certainly very good :) because it becomes easier for us to compete with them for cool developers.
Criticism welcome!
Source: https://habr.com/ru/post/67991/
All Articles