Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, 20 December 2010

Automatic Update Of Moles References To Other Solution Projects

The situation: I have a solution with several projects in it. One of them is UnitTest project, that uses Moles for mocking. And it has referenses to other projecs in solution as well as to their moled dlls. Every time I change code in my projects and rebuild them, the UnitTest project loses the references to moled dlls, as they allready have other versions. I see that Moles builds new versions of projects' dlls, but it does not update references. Why?

RTFM, Juri.

From the Microsoft Moles Reference Manual (page 12)

The Moles framework for Visual Studio monitors build events and automatically forces the regeneration of stub types for projects that have been updated. For efficiency reasons, this automatic update only works for .moles files that are in the top level folder of the project, to avoid walking large nested project structures. This automatic update creates a smooth experience when writing code in a test-driven development style.

So the automatic update of references works only for .moles files that are in the same folder with the project file. But I have moved all the .moles files into separate folder.

Now that I moved all the .moles files back, it is working.

Wednesday, 14 July 2010

C# Function That Mimics SQL IN-operator

A good question was asked on stackoverflow, and an even better answer received.

How can we rewrite the condition

if (a == x || a == y || a == z)

to make it more readable?

The answer is

public static bool IsIn<T>(this T obj, params T[] collection) {
   return collection.Contains(obj);
}

if (a.IsIn(x, y, z))

PS. Sorry for such a long period with no posting. You know, summer, Sun, beach, sea, +30 and vacation.

Thursday, 20 May 2010

Replacing Text In Html (Outside Html Tags)

private const string OUTSIDE_TAG_LOOKAHEAD = "(?![^<]+>)";

public static string HighlightWordsInHtmlText( string htmlText, params string[] words ){
  if (words == null || string.IsNullOrEmpty(htmlText) ) return htmlText;
  Regex regex = new Regex(OUTSIDE_TAG_LOOKAHEAD + "("+ string.Join("|", words) +")", RegexOptions.IgnoreCase);
  return regex.Replace(htmlText, "<span class=\"highlight\">$&</span>" );
}
OUTSIDE_TAG_LOOKAHEAD - uses regular expression magic, that matches text inside tags, but as it is negated, the text matched is really outside of html tags.
$& - refers to the current match. We cannot put here any word as we don't precisely know what of them was found and in what case.
This example matches also tron in strong, if you need an exact match add word boundaries like that:
OUTSIDE_TAG_LOOKAHEAD + "\\b("+ string.Join("|", words) +")\\b"

Tuesday, 4 May 2010

Escaping Curly Bracket in String.Format()

If you need to print a curly bracket in string, when using string format, just put it twice in a row.

string.Format("{{ hello world }}")//{ hello world };
string.Format("{{0}}", 45);//{0}
string.Format("{{{0}}}", 45);//{45}
string.Format("{0:N}", 45);//45.00
string.Format("{{{0:N}}}", 45);//{N}

The last one is not `{45.00}`, because the parser when reading `}}}` first prints the escaped `}`, and only then closes the formatting section. And as `N}` number format does not mean anything to it, it just prints it out.

Sunday, 20 December 2009

Date Parsing In C#

DateTime.Parse("Dec 13 18:06");//Results in {06.12.2009 13:18:00}
Why?!

Sunday, 15 November 2009

Add List To App.Config

One can add list and not only a list to App.Config file of the .Net project. That can be done by declaring your own configuration element, say a ProductElement

class ProductElement : ConfigurationElement
{
  [ConfigurationProperty("name", IsKey=true, IsRequired=true)]
  public string Name
  {
    get { return this["name"]; }
  }

  [ConfigurationProperty("price")]
  public int Price
  {
    get { return Convert.ToInt32(this["price"]); }
  }
}

class ProductElementCollection : ConfigurationElementCollection
{
  protected override ConfigurationElement CreateNewElement()
  {
    return new ProductElement();
  }

  protected override object GetElementKey(ConfigurationElement element)
  {
    return ((ProductElement)element).Name;
  }
}

class ProductConfigurationSection : ConfigurationSection
{
   [ConfigurationProperty("products")]
   public ProductElementCollection Products
   {
      get { return (ProductElementCollection)this["products"]; }
   }
}

Use it in your app.config like that:

<configuration>
   <configSections>
      <section name="productConfigurationSection"
        type="MyNamespace.ProductConfigurationSection, MyAssembly" 
        requirePermission="false" />
   </configSections>
   <productConfigurationSection>
      <products>
         <add name="car" price="750000" />
         <add name="milk" price="13" />
      </products>
   </productConfigurationSection>
</configuration>

Note that Name is used as a key, so you cannot create 2 Products with the same name. But you can add more fields to the Product, just mark them accordingly. And from code you can access this section with:

ProductConfigurationSection section = (ProductConfigurationSection) ConfigurationManager.GetSection("productConfigurationSection");

Sunday, 7 June 2009

Array To String

Oh, how I hate String.join(string, string[]) in mscorlib. And it is because of string[] argument. Why couldn't they make it accept array of objects and, before joining, cast every object with ToString() method?

Had to make it myself:

public string ListJoin<T>(string separator, T[] objs)//C# v3
{
  return string.Join(separator, Array.ConvertAll(objs, item => item.ToString()));
}

public string ListJoin<T>(string separator, T[] objs)//C# v2
{
  return string.Join(separator, Array.ConvertAll<T,string>(value, new Converter<T,string>(delegate(T i){return i.ToString();})));
}

Thursday, 14 May 2009

Export String Values To Excel 2007

If you encounter a following error, while exporting to Excel 2007 (.xlsx)

Errors were detected in file MyFileName.xlsx. Repaired Records: Cell information from /xl/worksheets/sheet1.xml part

then, probably, you are exporting string values in wrong format. The right structure in this case is

<sheetData>
  <row>
   <c>
     <v>99999</v>
   </c>
   <c t="inlineStr">
     <is>
       <t>My Text</t>
     </is>
   </c>
  </row>
</sheetData>

Note, that there is no <v> tag in <c> as it should be with numbers. Instead you have to make an inline string (<is>) tag and put text (<t>) tag with needed text in it. Do not forget to add the t="inlineStr" attribute to <c> tag.

More info can be found developer:network.

Monday, 27 April 2009

Method with arbitrary number of parameters in C#

One can also create a method with variable number of parameters in C#. It is needed, for example, when you have such logic, where you need to take value from one place, if it is not null, or from the other, or from the third place, if the first two are nulls, and so on. This can help:

public static T FirstNotNull<T>(params Nullable<T>[] objects) where T : struct
{
  foreach (Nullable<T> obj in objects)
    if (obj.HasValue) return obj.Value;
  return default(T);
}

Reserved word params shows, that we deal with an array of parameters. This parameter can only be the last one in a function. You can put other types of parameters before, but no after.

The function can be called like that:

HelperClass.FirstNotNull<int>(firstValue, secondValue, thirdValue, fourthValue);

The first not null value of these four is returned, or default value of the type, if all are nulls.

Tuesday, 31 March 2009

System.Reflection To the Rescue

Many people ask if there is a possibility to call a method, if we have its name as string. Actually, it is very useful feature. Imagine we have an Object with several properties which represent the same thing, but in different languages.

class MyClass
{
    public string State_EN;
    public string State_DE;
    public string State_RU;
}

We want to show the state of MyClass object in proper language. We create a method for that

public string State(string language)
{
}

Language is the 2-letter code representation of language ("EN", "DE", "RU"...). So what should be inside the State method? Solutions with "if" and "switch" are not good - if you have to add more languages, you must rewrite the State method. But we are lazy and don't want to do that. What we need here is System.Reflection.

using System.Reflection;
[...]
public string State(string language)
{
    PropertyInfo property = typeof(MyClass).GetProperty("State_" + language);//find the property
    if (property != null)
        return (string)property.GetValue(this, null);//get value of the property
    return null;
}

The same way we can search for method, if we know the method's name (with GetMethod instead of GetProperty). And call it with "Invoke" and proper parameters.

Wednesday, 18 March 2009

Using Generics With System.Nullable<T>

When we have a Nullable type value and we want to assign it to some control, then we need to check if is not null first.

SomeLabel.Text = object.MyProperty.HasValue ? object.MyProperty.Value : String.Empty;

But if we have many nullable properties? I don't want to copy/paste this check on every line. So we need a method, that checks for nulls. But I also don't want several methods for every type. So we need to use generics.

I created some methods for myself

public static string ValueOrEmptyString<T>(Nullable<T> obj) where T : struct
{
  return obj.HasValue ? obj.Value.ToString() : "";
}

public static T ValueOrDefault<T>(Nullable<T> obj, T defaultValue) where T : struct
{
  return obj.HasValue ? obj.Value : defaultValue;
}

public static T ValueOrDefault<T>(Nullable<T> obj) where T : struct
{
  return obj.HasValue ? obj.Value : default(T);
}

"where T : struct" - is needed for compiler to understand that this method is allowed only for types that belong to System.ValueType.

I can use these methods like that

SomeLabel.Text = ValueOrEmptyString<int>( object.MyIntProperty );
SomeDateTimeControl.Date = ValueOrDefault<DateTime>( object.MyDateTimeProperty );
SomeReferenceControl.SelectedObjecId = ValueOrDefault<int>( object.MyIntProperty, -1 );

Tuesday, 15 July 2008

Первые впечатления

Итак, делюсь первыпи впечатлениями, как ощущения после перехода с Ruby на C#. Пока всё, с чем я столкнулся, это неудобства:

Null class.
Отсутствие null как объекта. Затрудняет жизнь многочисленными провернками на null. Паттерн introduce null object не особо спасает. Писать для каждого класса нулевой объект не радует. Можно ли реализовать 1 общий класс, от которого всё наследуется?
System.Linq библиотека
Вроде бы удобная вещь, но! Она была нагло спислизана с ruby, причём сделано это очень криво. Зачем-то нужно было менять названия методов. Плюс были портированы не 1 в 1. В результате имеем:
Method alternatives
RubyC#
array.collectarray.select
array.selectarray.Where
array.detect ( = array.select.first )array.first
array.join( token )String.join(array, token)
Как видим, join метод стал вдруг методом String класса.
Много лишних слов
public overrride static void methodName() vs. def self.method_name
Консоль
Отсутствие консоли, где можно быстренько потестить какой-нибудь метод.

Или я просто предвзято отношусь к C# и Microsoft?