Home .NET Utipization inC#

Utipization inC#

by admin

The multifaceted Sherlock Holmes and Erast Fandorin, the perfect aristocrat, were both very venerable for the deductive method and both achieved stunning success in its application."Discard all that is impossible, what remains will be the answer, however improbable it may seem, " sosaid Sir Arthur Conan Doyle in the mouth of his hero.
However, the science of reasoning does not end with deductive inferences – we should not forgetabout induction as well.This treatise will treat of it and of approximate matter.

Ducktest

Induction is a process of logical inference based on the transition from particular statements to the general.The famous "duck test" is a prime example of such a process :

If it walks like a duck and quacks like a duck, it must be a duck
(If someone walks like a duck and quacks like a duck, then it’s a duck)

When applied to programming languages – particularly to object-oriented languages – the "duck test" takes on a special meaning. In dynamically typed languages, the semantics of usingthis or that objectis determined by the current set of its methods and properties. For example, in a statically typed language that does not support utipization, you can create a function that takes a classobjectas a parameter Duck and calls the methods Quack and Walk of this object. In a utility-typed (and, hence, dynamically typed) language, asimilar function can take an abstract object as a parameter and try to call the same methods from it (possibly by checking its existence). In a statically typed language, this behavior can be achieved usinginheritance and implementation of interfaces, but it would be an expression of the form is-a , as opposed to has-a in dynamic languages.
Having briefly explained what utipization is and why it is not available in statically typed languages, I will now slightly refute myself. This may not be a revelation to some, but nevertheless. C# also has some kind of duck typing. Let’s look more closely into this subject in a moment.

foreach

Syntactic sugar can be a little sweeter than it first appears. In particular, this applies to the operator foreach Most textbooks say that to support the semantics of foreach classmust implement (explicitly or implicitly) the interface System.Collections.IEnumerable In fact, this is not entirely true- as far as C# is concerned, you don’t have to implement the mentioned interface at all.
If you open the C# Language Specification and look in section 8.8.4 you will see the following :

The type of the expression of a foreachstatement must be a collection type (as defined below), and an explicit conversion (§6.2) must exist from the element type of the collection to the type of the iteration variable. If expression has the value null , a System.NullReferenceException is thrown.
A type C is said to be a collection type ifit implements the System.Collections.IEnumerable interface or implements the collection pattern by meeting all of the following criteria:

  • C contains a publicinstance method with the signature GetEnumerator() that returns a struct-type, class-type, or interface-type, which is called E in the following text.
  • E contains a publicinstance method with the signature MoveNext() and the returntype bool
  • E contains a publicinstance property named Current that permits reading the current value. The type of this property is said to be the element type of the collection type.

So the following code will compile perfectly and output what it is supposed to output to the console :

using System;
using System.Collections. Generic ;
namespace DuckTyping
{
class Collection
{
public EnumeratorGetEnumerator()
{
return new Enumerator();
}
}
class Enumerator
{
private bool moveNext = true ;
public object Current
{
get { return "Enumerator.Current" ;}
}
public bool MoveNext()
{
if (!moveNext)
return false ;
moveNext = false ;
return true ;
}
}
class Program
{
static void Main()
{
foreach ( object o in new Collection())
Console writeLine(o);
}
}
}
* This source code was highlighted with Source Code Highlighter

Small thing, I’m pleased.

Collection Initializers

Quite a nice newfeature in C# 3.0. Recall :

var digits = new List < int >{0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
* This source code was highlighted with Source Code Highlighter

That would be fine, but all that’s left is to define the term "Collection". And that’s where we have a problem.
Interface System.Collections.ICollection Before .NET 2.0 was a completely useless creature. In 2.0 they fixed it : System.Collections.Generic.ICollection<T> allows to add and remove items, to pass through them with the already mentioned foreach and get the number of elements in the collection.
It would seem that the solution has been found: any class that implements the ICollection<T> and will be called a collection. But that’s not the case – almost no one implements it. Out of thousands of .NET BCL classes, only a few dozen can boast that they have a publicly available constructor without parameters and can be brought to ICollection<T>
No one thought of giving up in the C# Design Group. We decided to use a well-proven Pattern-based syntax – namely, to call the Add() if there is one at all. Now, the requirements to the collection from the point of view of the Collection Initializer are as follows: implementation of IEnumerable and having at least one publicly available method Add()
The item "having at least one…" requires a little clarification. The list of items enclosed in curly braces is not a "list of items to add" – it is a "list of arguments for methods Add() ". The argument list, therefore, can be heterogeneous. In other words, having such a class :

public class Plurals : IDictionary< string , string >
{
public void Add( string singular, string plural);
public void Add( string singular);
public void Add(KeyValuePair< string , string > pair);
}
* This source code was highlighted with Source Code Highlighter

the following initializer would be quite legal :

var myPlurals = new Plurals{ “collection”, { “query”, “queries” }, new KeyValuePair(“child”, “children”) };
* This source code was highlighted with Source Code Highlighter

Since allowing overloads is done separately for each element in the initialization list, all three methods will be involved.

In lieu of a conclusion

Sherlock Holmes, Erast Petrovich, and yours truly take a bow. I hope it was interesting.
Thanks Dr. T For food for thought.

You may also like