Sunday, December 22, 2013

Dependency Properties' key features

In progress...


The purpose of dependency properties is to provide a way to compute the value of a property based on the value of other inputs.

Main features:
Reduced memory footprint
  90% of the properties of a UI control typically stay at its initial values
  The default values are stored once within the dependency property.
Value inheritance
  Value resolution strategy.
    If no local value is set, the dependency property navigates up the logical tree until it finds a value.
  Not good practice cause performance impact.
  The main example is the DataContext.
  Property value inheritance is not the default property system behavior; a property must be established with a particular metadata setting in order to cause that property to initiate property value inheritance on child elements.
Change notification
  used by the databinding
  used by a custom logic

Details:
Value Precedence
  ...
Metadata Overrides
   Call in a constructor the AnyProperty.OverrideMetadata(...)
Pattern (creating)
  Inheritance from the DependencyObject that defines a key, value dictionary that contains local values.
    DependencyObject class, do not natively support INotifyPropertyChanged.
  DependencyProperty.Register() with yours static field.
  A name must always end up with Property - naming convention.
  A property wrapper with no logic.
    XAML ignores the wrapper and calls directly the DependencyObject's SetValue, GetValue.
  propdp - the shortcut initiator in VS.
  Callbacks
    Value Changed Callback
    Coerce Value Callback
      Correction of a new value without throwing an exception
    Validation Callback
      ArgumentException
  Readonly DependencyProperties
    private static readonly DependencyPropertyKey MyPropertyKey = DependencyProperty.RegisterReadonly(...)
    public static readonly DependencyProperty MyProperty =  MyPropertyKey.DependencyProperty;
    public int My
    {
       get { return (bool)GetValue(MyProperty); }
       private set { SetValue(MyPropertyKey, value); }
    }
  Attached Properties
    DependencyProperty.RegisterAttached
    GetPropertyName and SetPropertyName static methods.
    Has no wrapper in an instance.
Attach to events of defined properties
DependencyPropertyDescriptor
  DependencyPropertyDescriptor textDescr = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
  textDescr.AddValueChanged(myTextBox, delegate
How to clear a local value
  DependencyProperty.UnsetValue
  button1.ClearValue( Button.ContentProperty );
Safe Constructor Patterns for DependencyObjects.

Literature
  MSDN
  http://wpftutorial.net/DependencyProperties.html

Binding.Path syntax

All possible things of the Binding's Path

See Binding.Path Property - Remarks (MSDN)

Explicit interface implementation Anti-pattern.

Explicit interface definition forces the members to be exposed only when you are working with the interface directly.

The main words are: Unexpected Behavior

Mostly used:
  • Implementing of several interfaces with the same members required different implementation.
  • Struggle with dependencies (very doubtful).
    Code with using more derived types knows nothing about interface's members that were implemented explicitly.
    For example in a ASP.NET MVP (Web Forms) control hide member used by presenter.
  • Work around for having same member with different logic in an interface and its derived class.
  • Some silly protection (by a run-time exception) from using of inappropriate interface members.
    As an example the array's explicit implementation for the ICollection<T>.Add() that will throw the NotSupportedException "Collection of a fixed size".

 Famous drawbacks:
  • It's greasy messy awful coding especially when used without a serious reason.
    It's definitely not an industrial programming.
  • Value type instances will be boxed when casted to an interface.
  • Cannot be called by a derived type
    (What is the struggle with dependencies on the other hand).
  • A virtual chain will be ignored and an explicit implementation will be called.
.
Microsoft's official guidelines (from first edition Framework Design Guidelines) states that using explicit implementations are not recommended, since it gives the code some unexpected behavior.
.
interface IMyInterface
{
    String Implicit { get; set; }
    String Explicit { get; set; }
    String ExplicitAndImplicit { get; set; }
    String OtherExplicit { get; set; }
}


interface IMyOtherInterface
{
 
   String OtherExplicit { get; set; }
}


class MyClass : IMyInterface, IMyOtherInterface
{
 
   String IMyInterface.Explicit { get; set; }

    String IMyInterface.ExplicitAndImplicit { get; set; }
    public String ExplicitAndImplicit { get; set; }

    public String Implicit { get; set; }

    String IMyInterface.OtherExplicit { get; set; }
    String IMyOtherInterface.OtherExplicit { get; set; }
    public String OtherExplicit { get; set; }
}

static void Main(string[] args)
{

    var myObject = new MyClass();
    var myInterface = (IMyInterface) myObject;
    var myOtherInterface = (IMyOtherInterface)myObject;

    myObject.Implicit = "Implicit";

    // Uncompilable code.
    //myObject.Explicit = "Explicit for the MyClass";
    myInterface.Explicit = "Explicit for the IMyInterface";

    myObject.ExplicitAndImplicit = "ExplicitAndImplicit for the MyClass";
    myInterface.ExplicitAndImplicit = "ExplicitAndImplicit for the IMyInterface";
    if(myObject.ExplicitAndImplicit == myInterface.ExplicitAndImplicit)
    {
        throw new Exception("Blow mind");
    }

    myInterface.OtherExplicit = "OtherExplicit for IMyInterface";
    myOtherInterface.OtherExplicit = "OtherExplicit for IMyOtherInterface";
    myObject.OtherExplicit = "OtherExplicit for MyClass";
    if (myInterface.OtherExplicit == myOtherInterface.OtherExplicit
        || myOtherInterface.OtherExplicit == myObject.OtherExplicit)
    {
        throw new Exception("Blow mind");
    }

}
.

The C# Dynamic Properties' implementation and a full Expando

It's implemented by the DynamicObject from .NET Framework.
Just an straightforward example in the MSDN - DynamicObject Class.

Wow! But also we have the ExpandoObject.

Some tip from MSDN
The ExpandoObject class is an implementation of the dynamic object concept that enables getting, setting, and invoking members. If you want to define types that have their own dynamic dispatch semantics, use the DynamicObject class. If you want to define how dynamic objects participate in the interoperability protocol and manage DLR fast dynamic dispatch caching, create your own implementation of the IDynamicMetaObjectProvider interface.
dynamic sampleObject = new ExpandoObject();

sampleObject.test = "Dynamic Property";
// Create a new event and initialize it with null.
sampleObject.sampleEvent = null;
// Add an event handler.
sampleObject.sampleEvent += new EventHandler(SampleHandler);

Main features:
  • Dynamic properties and methods
  • Enumerating and Deleting Members
  • !!!
    Receiving Notifications of Property Changes with the INotifyPropertyChanged.
    I.e. it supports the Data Binding with Change Notifications out of the box.
The ExpandoObject class implements the INotifyPropertyChanged interface and can raise a PropertyChanged event when a member is added, deleted, or modified. This enables ExpandoObject class integration with Windows Presentation Foundation (WPF) data binding and other environments that require notification about changes in the object content.
.

Friday, November 22, 2013

.Net Contravariance & Covariance notes

Variant == Contravariant or Covariant.
Invariant == NOT (Contravariant or Covariant)

All next members of an interface will result in compilation errors.
interface IVariant<out TReturn, in TArgument>
{
    // CS1961 Invalid variance:
    // The type parameter 'TReturn' must be contravariantly valid on 'IVariant<TReturn, TArgument>.SetA(TReturn)'.
    // 'TReturn' is covariant.
    void SetA(TReturn smpleArg);

    // CS1961 Invalid variance:
    // The type parameter 'TArgument' must be covariantly valid on 'IVariant<TReturn, TArgument>.GetA()'.
    // 'TArgument' is contravariant.
    TArgument GetA();

    // CS1961 Invalid variance:
    // The type parameter 'TArgument' must be covariantly valid on 'IVariant<TReturn, TArgument>.GetASetR(TReturn)'.
    // 'TArgument' is contravariant.
    // CS1961 Invalid variance:
    // The type parameter 'TReturn' must be contravariantly valid on 'IVariant<TReturn, TArgument>.GetASetR(TReturn)'.
    // 'TReturn' is covariant.
    TArgument GetASetR(TReturn sampleArg);
}

So, there are rules for the "in" and "out".

Contravariance is the "in" parameter.
    Contravariance permits a method to have argument types that are less derived than that specified by the generic parameter of the interface.
    The contravariant type can be used only as a type of method arguments and not as a return type of interface methods.
    Only the contravariant type can be used for generic constraints. Not invariant or covariant types!

Covariance is the "out" parameter.
    Covariance permits a method to have a more derived return type than that defined by the generic type parameter of the interface.
    The type is used only as a return type of interface methods and not used as a type of method arguments.
    There is one exception to this rule. If you have a contravariant generic delegate as a method parameter,
        you can use the type as a generic type parameter for the delegate.
        interface ICovariant<out R>
        {
            void DoSomething(Action<R> callback);
           
            // Compiler error: void DoSomething(R param);
        }

Generic Interfaces
Classes that implement variant interfaces are invariant.
    IEnumerable<Object> listObjects = new List<String>();
    // Compiler error: List<Object> list = new List<String>();
The compiler does not infer the variance from the interface that is being extended.

If a generic type parameter T is declared covariant in one interface, you cannot declare it contravariant in an extending interface, or vice versa.
    interface ICovariant<out T> { }
    // Compiler error: interface ICoContraVariant<in T> : ICovariant<T> { }

Ambiguity. Can lead to subtle bugs in your code.
    The compiler does not produce an error
    class Pets : IEnumerable<Cat>, IEnumerable<Dog>

Array Covariance Collision
Array Covariance turns compile-time exceptions into run-time exceptions.

In .NET all types derived (inherited) from the Object type.
For example String is derived from Object.
But an array of strings string[] is not derived from an array of objects object[].
Nevertheless .NET implements a feature that known as Array Covariance.
That means that we can implicitly cast a derived[] array to a base[].

  string[] stringArray = {"a"};
  object[] objectArray = stringArray;
  // ArrayTypeMismatchException here.
  objectArray[0] = 1;

Delegates
    For an assigning of method (lambda expression) to a delegate there is an implicit conversion with the Contravariance & Covariance.
        It has no trouble.
        Framework 4. The point of the variance is the implicit variance conversion between delegates.
    Variance is supported for reference types only.
        For value types variance is ignored.
    You should not combine variant delegates
        run-time exception

Properties
You get the compiler error because you have a property getter (get) and a setter (set).

Tuesday, November 12, 2013

How to invoke an event handlers asynchronously

How to invoke an event or delegate handlers asynchronously

Variant with the Parallel class (TPL).
public void OnMyEvent(String myValue)
{
    var multiCastDelegate = Interlocked.CompareExchange(ref MyEvent, null, null);
    if (multiCastDelegate == null)
    {
        return;
    }

    var handlers = multiCastDelegate.GetInvocationList()
        .Cast<EventHandler<MyEventArgs>>();

    var args = new MyEventArgs(myValue);
    Parallel.ForEach(
        handlers,
        handler => handler(this, args));
} 

Old variant with the Asynchronous delegates (APM).
public void OnMyEventOld(String myValue)
{
    var multiCastDelegate = Interlocked.CompareExchange(ref MyEvent, null, null);
    if (multiCastDelegate == null)
    {
        return;
    }

    var handlers = multiCastDelegate.GetInvocationList()
        .Cast<EventHandler<MyEventArgs>>();
    foreach (var handler in handlers)
    {
        var args = new MyEventArgs(myValue);
        handler.BeginInvoke(
            this,
            args,
            asyncResult =>
                {
                    var asyncDelegate = (EventHandler<MyEventArgs>)((AsyncResult)asyncResult).AsyncDelegate;
                    try
                    {
                        asyncDelegate.EndInvoke(asyncResult);
                    }
                    catch (Exception ex)
                    {
                        ProcessException(ex);
                    }
                },
            null);
    }
}


Aggregating Exceptions
Should event handlers in C# ever raise exceptions?
Thread Safe Event Calls
Release IS NOT Debug: 64bit ...

Saturday, October 26, 2013

Binding lack of the Silverlight DataGrid CellTemplate

Be aware of this.
Silverlight 5.
DataGrid
DataGridTemplateColumn.CellTemplate
Visibility (!!!)
It doesn’t work, at all:
Visibility="{Binding Path=Detail, Converter={StaticResource VisibleNonEmptyConverter}}"
This is working:
Visibility="{Binding Path=DataContext, RelativeSource={RelativeSource Self}, Converter={StaticResource VisibleNonEmptyConverter}}"
DataContext="{Binding Path=Detail}"
<data:DataGrid
               ItemsSource="{Binding Path=Items}"
               AutoGenerateColumns="False"
               HeadersVisibility="None"
               Background="Transparent"
               HorizontalAlignment="Left"
               HorizontalContentAlignment="Left"
               VerticalContentAlignment="Center"
               AlternatingRowBackground="LightGray"
               RowBackground="White"
               >
               <data:DataGrid.Columns>
                               <data:DataGridTextColumn Binding="{Binding Path=Name}" IsFrozen="True" IsReadOnly="True"/>
                                                                            
                               <data:DataGridTemplateColumn>
                                              <data:DataGridTemplateColumn.CellTemplate>
                                                             <DataTemplate>
                                                                            <Grid
                                                                                           VerticalAlignment="Center"
                                                                                           DataContext="{Binding Path=Value}"
                                                                                           >
                                                                                            <Grid.ColumnDefinitions>
                                                                                                           <ColumnDefinition/>
                                                                                                           <ColumnDefinition Width="auto"/>
                                                                                            </Grid.ColumnDefinitions>
                                                                                                                                          
                                                                                           <TextBlock Text="{Binding Path=Exact}" VerticalAlignment="Center" Margin="3 0"/>
                                                                                                                                          
                                                                                            <!--, FallbackValue=Collapsed, TargetNullValue=Collapsed-->
                                                                                            <Image
                                                                                                           Grid.Column="1"
                                                                                                           Source="/HCFB.UFO.Web;component/Resources/Images/info.v2.png"
                                                                                                           Width="16"
                                                                                                           Margin="3 1"
                                                                                                           VerticalAlignment="Center"
Visibility="{Binding Path=DataContext, RelativeSource={RelativeSource Self},
                    Converter={StaticResource VisibleNonEmptyConverter}, FallbackValue=Collapsed}"
DataContext="{Binding Path=Detail}"
                                                                                                           MouseLeftButtonUp="DetailImage_MouseLeftButtonUp"
                                                                                           />
                                                                            </Grid>
                                                             </DataTemplate>
                                              </data:DataGridTemplateColumn.CellTemplate>
                               </data:DataGridTemplateColumn>
               </data:DataGrid.Columns>
                                                             
</data:DataGrid>