Thursday, March 23, 2017

C# Things I've Been Learning Lately

How to convert a specific type into a generic type
(From the C# error message "cannot convert type xyz  to 'T')
The magic is in "Task.FromResult((T) Convert.ChangeType(result, typeof(T)));"
This is not considered good practice, but this is a  contrived example of implementing a mock for a GetAsync() method.

        

       public async Task GetAsync(string url)
        {
            return await Task.Run(() => GetAnimal(url));
        } 

       private Task GetAnimal(string url)
        {
            string result = null;
            if (url.Contains("mammal"))
            {
                result = "Giraffe";
            }
            ....
            return Task.FromResult((T) Convert.ChangeType(result, typeof(T)));
        }





How to use Console.WriteLine() in MVC .Net Applications for Debugging.

The easiest way is to use "Debug" statements like this:

Debug.WriteLine($"animal = {animal}");

Make sure in your project's Properties that Build/"Define DEBUG constant" is checked.
Then your debug statements will appear in the "Output" window.



How to selectively return values from Moq.  Recently I needed to return different values from long strings of input to Moq.  I was delighted to know the It.Is will take a lambda expression returning true or false.


var vetMoq = new Mock<IVeterinarian>();
/*
string url1 = "asdflksdflfklklsjss Tiger asdfasdfasdfas";
string url2 ="asdflksdflfklklsjss Horse asdfasdfasdfas";
*/
vetMoq.Setup(animal => animal.Diet(It.Is<string>(url => url.Contains("Tiger")).Returns("carnivore");
vetMoq.Setup(animal => animal.Diet(It.Is<string>(url => url.Contains("Horse")).Returns("herbivore");




How to iterate over Enum types:
foreach (var myType in 
   Enum.GetValues(typeof(MyType)).Cast<MyType>())
{
...
}

How to create a case-insensitive dictionary with a "string" key and a "MyType" value.
private static readonly Dictionary< string, MyType> _dictionary = 
  new Dictionary<string, MyType>(StringComparer.InvariantCultureIgnoreCase);
The Dictionary class takes an optional parameter of IEqualityComparer<tkey>. By passing in "StringComparer.InvariantCultureIgnoreCase" you create a dictionary that is case-insensitive for the string keys.

How to capitalize the first letter of each word in a string? String functions "ToUpper()" and "ToLower()" have a cousin, "ToTitleCase()" that capitalizes the first letter in each word
System.Globalization.TextInfo textInfo = 
        new System.Globalization.CultureInfo("en-US", false).TextInfo;
title = textInfo.ToTitleCase("we hold tHese tRuths tO be Self evident"); 
//We Hold These Truths To Be Self Evident

How to read data from an embedded file? First add the file to your project and set its Property "Build Action" to "Embedded Resource".
var assembly = Assembly.GetExecutingAssembly();
var name = assembly.GetName().Name;
var resourceName = $"{name}.MyTextFile.txt";

using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
    using (StreamReader reader = new StreamReader(stream))
    {
        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
     ...
        }
    }
}

No comments: