Archive

Posts Tagged ‘Methods’

Suggestion: C# static extension methods invokable on class type too

it would be nice if C# supported syntax like:

public static DependencyProperty Register(static DependencyProperty x, string name, Type propertyType, Type ownerType, FrameworkPropertyMetadata typeMetadata)

that is static extension methods for classes, that can be invoked without a class instance (just with the class type), apart from normal extension methods that can be invoked on a class instance.

Then for example I could use it in Silverlight to add to its DependencyProperty class some extra WPF syntax that it currently misses, in order to increase code portability. It would wrap Dr.WPF’s implementation of value coercion for Silverlight’s DependencyProperty. I have the related code at my Compatibility library (http://Compatibility.codeplex.com) and respective NuGet package (http://nuget.org/packages/Compatibility), but the syntactic sugar is missing to achieve source code portability (via WPF and Silverlight projects that include common files via file links) without changes.

Note the "static DependencyProperty" parameter instead of the "this DependencyProperty" one that is used in C# extension methods (or else instead of static maybe they could use other keyword like type or typeof there, but I feel static is more appropriate).

Related discussion:

http://stackoverflow.com/questions/866921/static-extension-methods

http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class

Also see https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f where somebody mentions "static extension properties" apart from "extension properties". Indeed it is natural that if static extension methods are to be allowed in the future, static extension properties should be added too (to extend a type with [attached] static properties)

You can vote for a related suggestion here:

https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f

Suggestion: Introduce .= operator for C#

It would be nice if one could write in C# (and maybe in other .NET languages too):

s = s.SomeMethodOfS(…)…

as

s .= SomeMethodOfS(…)…

that is to have a .= operator, similar to += and other shorthand experession operators

see screenshot for an example usecase from the opensource project FoscamController

image

Ideally, usage of such operators should lead to compiling – whether is is via JIT (Just in Time) or AOT (Ahead of Time) compilation – into more optimized native code, but I’m not sure if C# compilers are exploting that optimization opportunity.

You can vote up this suggestion at:
http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/10724280-introduce-operator-for-c

Suggestion: Define once and reuse result type of method inside its body

It would be nice if one could rewrite this C# snippet:

public SortedDictionary<string, UObject> GetObjects()
{
SortedDictionary<string, UObject> result = new SortedDictionary<string, UObject>();
using (ReadTransaction xact = namingSchema.ReadTransaction())
foreach (ObjectName.RowType row in ObjectName.object_name_(xact))
result.Add(row.name_, row.object_);
return result;
}

 

in a more concise form like:

 

public T GetObjects() where T=SortedDictionary<string, UObject>
{
T result = new T();
using (ReadTransaction xact = namingSchema.ReadTransaction())
foreach (ObjectName.RowType row in ObjectName.object_name_(xact))
result.Add(row.name_, row.object_);
return result;
}

 

In case you wonder what this code is doing, it is getting Ubisense objects and their names, for the whole sample see http://UbisensePositioning.codeplex.com

You can vote on this suggestion at:

http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/10724304-define-once-and-reuse-result-type-of-method-inside

Suggestion: Allow local nested methods inside any code block

It would be nice if one could define methods inside other methods so that they are only accessible in the context of the parent method. In Pascal one could define them at the start of the parent method, before any other commands, but after local variables block, so they could also access the variables of their parent proc.

A trick to implement them could be to make them anononymous methods and assign them to respective local delegates inside the parent method. That way one could also do arbitrary level of such nesting.

Ideally they would also accept an optional inline keyword so that the compiler can inline them (useful for short methods) inside the parent method body (that is the only one allowed to call them anyway [they’re not visible from outside classes or other codeblock in the same class]).

For example, when I refactor code to split a big method to call into other smaller methods, I want them sometimes only to be callable from that original method, and not be accidentally called from elsewhere in my code, including elsewhere in the same class.

Note that in Object Pascal/Delphi such nested methods/procedures/functions could access variables defined at the parent method/procedure/function, since you define them always at the top before the local code.

Implementing the inner methods like you do with anonymous methods allows to grab such local context I believe, so you could allow such inner methods to be defined anywhere inside code blocks to allow access to the variables defined above them in the current code block.

Example syntax suggested:

public void SomeMethod(int i)

{

  if(i>10)

{

    int y = 2;

    void increment(int x) { i = i+x+y; }

    increment(5);

  }

  doSomething( i );

}

 

image

In this screenshot from my enhanced version of Hotspotizer (currently adding speech recognition to that Kinect-based full-body-gestures automation app), I’d like InitSpeechRecognition to only be callable from inside LoadSpeechRecognitionPlugin. I use two methods there to split a bigger method, but I don’t want the 2nd one to be accidentally called from elsewhere in my code.

If you like this suggestion, please vote for it at:
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/9639582-allow-nested-methods-inside-any-code-block

Update:

  • Visual Studio Team commented:

You can do this today:

“`
public void SomeMethod(int i)
{
if (i > 10)
{
int y = 2;
Action<int> increment = x => { i += x + y; };
increment(5);
}
doSomething(i);
}
“`

It’s not the syntax you suggested, but it does do the same thing.

Bertrand Le Roy – .NET – Program Manager

 

  • And this is my reply:

Thanks for the pointer Bertrand, having worked with Object Pascal / Delphi for many years too I like its cleaner syntax on this one

HowTo: Call C# method from class that has same name as namespace

image

In the C# compiler error case shown above, CaptionsGrid class exists in namespace ClipFlair.CaptionsGrid so in the code we have “using ClipFlair.CaptionsGrid;” at the top of the file where we want to call the “SaveAudio” static method of CaptionsGrid class.

But then we get the error “The type or namespace name ‘…’ does not exist in the namespace ‘…’ (are you missing an assembly reference?)”

The solution is to use a more full identifier, that is use “CaptionsGrid.CaptionsGrid.SaveAudio(…)” or even use the full namespace path “ClipFlair.CaptionsGrid.CaptionsGrid.SaveAudio(…)”. In the last case you wouldn’t need the “using ClipFlair.CaptionsGrid” at all.

It is better to avoid naming the parent namespace part of a class with the same name as the class, but some times one can’t find a better name I guess.

.NET String extension methods to check for array of prefixes or suffixes

Seems StartsWith and EndsWith methods of String class in .NET are missing a version that accepts multiple (as an array) prefixes or suffixes respectively when testing the string. To achieve this I just added the following extension methods to StringExtensions class (of Utils.Extensions namespace) under Utils.Silverlight project at the ClipFlair source code.

public static bool StartsWith(
this string s,
string[] suffixes,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string suffix in suffixes) if (s.StartsWith(suffix, comparisonType)) return true; return false; } public static bool EndsWith(
this string s,
string[] suffixes,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string suffix in suffixes) if (s.EndsWith(suffix, comparisonType)) return true; return false; }

 

To use them, you add a reference to Utils.Silverlight project to your own one and then add a using clause for the namespace that hosts a static class with these extension methods (e.g. “using Utils.Extensions;”) and then you can use them on any String at the respective source file. Can even use them on literal strings, since most .NET compilers support Boxing of literals into respective types.

I’m using a default value for the comparisonType method argument to make it optional. I use StringComparison.CurrentCulture as the default value for it (performing a word case-sensitive and culture-sensitive comparison using the current culture), as Microsoft is doing at “String.StartsWith(String)” method. However, do note the following text from that method’s documentation:

Notes to Callers

As explained in Best Practices for Using Strings in the .NET Framework, we recommend that you avoid calling string comparison methods that substitute default values and instead call methods that require parameters to be explicitly specified. To determine whether a string begins with a particular substring by using the string comparison rules of the current culture, call the StartsWith(String, StringComparison) method overload with a value of StringComparison.CurrentCulture for its comparisonType parameter.

.NET String class extensions to replace prefix or suffix

Just added the following extension methods to StringExtensions class (of Utils.Extensions namespace) under Utils.Silverlight project at the ClipFlair source code.

public static string ReplacePrefix(
this string s,
string fromPrefix,
string toPrefix,
StringComparison comparisonType = StringComparison.CurrentCulture) { return (s.StartsWith(fromPrefix, comparisonType)) ?
toPrefix + s.Substring(fromPrefix.Length) : s; } public static string ReplacePrefix(
this string s,
string[] fromPrefix,
string toPrefix,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string prefix in fromPrefix) if (s.StartsWith(prefix, comparisonType)) return toPrefix + s.Substring(prefix.Length); return s; } public static string ReplaceSuffix(
this string s,
string fromSuffix,
string toSuffix,
StringComparison comparisonType = StringComparison.CurrentCulture) { return (s.EndsWith(fromSuffix, comparisonType)) ?
s.Substring(0, s.Length - fromSuffix.Length) + toSuffix : s; } public static string ReplaceSuffix(
this string s,
string[] fromSuffix,
string toSuffix,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string suffix in fromSuffix) if (s.EndsWith(suffix, comparisonType)) return s.Substring(0, s.Length - suffix.Length) + toSuffix; return s; }

 

To use them, you add a reference to Utils.Silverlight project to your own one and then add a using clause for the namespace that hosts a static class with these extension methods (e.g. “using Utils.Extensions;”) and then you can use them on any String at the respective source file. Can even use them on literal strings, since most .NET compilers support Boxing of literals into respective types.

e.g.

s = s.ReplacePrefix("https://&quot;, "http://&quot;, StringComparison.OrdinalIgnoreCase);

//– converts https:// prefix to http:// ignoring character case

or

s = s.ReplacePrefix(new String[]{"https://&quot;, "http://&quot;}, "", StringComparison.OrdinalIgnoreCase);

//– removes https:// or http:// prefix ignoring character case

 

Update:

I added a default value for the comparisonType method argument to make it optional. I use StringComparison.CurrentCulture as the default value for it (performing a word case-sensitive and culture-sensitive comparison using the current culture), as Microsoft is doing at “String.StartsWith(String)” method. However, do note the following text from that method’s documentation:

Notes to Callers

As explained in Best Practices for Using Strings in the .NET Framework, we recommend that you avoid calling string comparison methods that substitute default values and instead call methods that require parameters to be explicitly specified. To determine whether a string begins with a particular substring by using the string comparison rules of the current culture, call the StartsWith(String, StringComparison) method overload with a value of StringComparison.CurrentCulture for its comparisonType parameter.

%d bloggers like this: