Wednesday, October 24, 2012

C# implicit/explicit operator overloading

You can make your own class "castable" to any types explicitly or implicitly by overloading these operators:

class Person
    {
        public string Name { get; set; }
        public int Id { get; set; }

        public static implicit operator Person(int i)
        {
            return new Person() { Id = i };
        }

        public static implicit operator int(Person p)
        {
            return p.Id;
        }
    }
now you can use implicit cast between int and Person (on both directions) whenever you want.

static void Main(string[] args)
        {
            List l1 = new List();
            l1.Add(1);
            l1.Add(2);
            l1.Add(3);

            foreach(int i in l1)
                Console.WriteLine(i);
        }

Tuesday, October 9, 2012

P/Invoke - back to school with C like syntax

In this short demo I will demonstrate how to do P/Invoke with native C/C++ methods.


class Program
    {
        [DllImport("msvcrt.dll")]
        private static extern int printf([MarshalAs(UnmanagedType.LPStr)]string str);

        [DllImport("msvcrt.dll")]
        private static extern int puts(string s);

        static void Main(string[] args)
        {
            printf("Hi\n");
            puts("Back to school");
        }
    }

Output:

Monday, August 20, 2012

C# how to access private fields and methods

The answer is Reflection

    public class Test
    {
        private int _privateField;

        private void PrivateMethod(string str)
        {
            Console.WriteLine("This is private method, parameters: {0}", str);
        }

        public void PrintInfo()
        {
            Console.WriteLine("_privateField = {0}", _privateField);
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Type type = typeof(Test);

            MethodInfo method = type.GetMethod("PrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);
            FieldInfo field = type.GetField("_privateField", BindingFlags.NonPublic | BindingFlags.Instance);

            Test instance=new Test();

            method.Invoke(instance, new object[] { "I can access private members" });

            field.SetValue(instance, 1234567890);
            instance.PrintInfo();
        }
    }

The output is:


======================================================   This is private method, parameters: I can access private members
_privateField = 1234567890
======================================================

Sunday, August 5, 2012

WCF without [DataContract]-s

WCF does not require explicit mark for DataContractAttribute since .NET 3.5 SP1, so it is possible not to mark classes with that attribute and pass them with service operations as usual. This is called Inferred data contracts, WCF will mark your classes with [DataContract] and Public fields with [DataMember] attributes and it's OK.


    //[DataContract]
    public class Person
    {
        //[DataMember]
        private string Name { get; set; }
    }
This will work as well as with explicit mark with attributes. But it is RECOMMENDED to use [DataContract] attribute for "readability" reasons and etc.

Tuesday, July 24, 2012

C# easy way to create file on the Desktop

Sometimes you need to quickly create some temp file on the desktop e.g., for this you need to remember  and type full path of your desktop which usually is "c:\users\{username}\desktop" which is a bit HardCoded way, on the one hand you need to type long string by hand(one character mistake and path doesn't work :/), on the other hand you may need your "program" to do the same thing on another computer, which has different user name(so HardCoded method will fail).

There is very simple solution for this, System.Environment class and it's SpecialFolder included folders, which are almost all of Windows default folders: Desktop, My Documents, Temp and etc.

so yo can simply write:

StreamWriter wr = File.CreateText(
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.txt"));


which creates test.txt file on every computer's desktop it's launched.

Wednesday, July 18, 2012

Avoid WCF Add Service Reference duplicating data contracts

You can configure when "Add Service Reference" by checking "Reuse types in referenced assemblies" and choose those assemblies containing data contracts.

note:
than it will only generate .config, proxy class with "SomeService+Client", contract interface for service and "contract+chanel" interface(which is derived from both your service contract and "IClientChannel", it allow you to call your interface methods plus IClientChannel methods like Close() and Abort()).

Visual Studio Pre/Post build event made easy

Sometimes I need to copy all my dll's and output files into single directory, (last time I had to merge all assemblies into one .exe file with ILMerge tool ILMerge(easy and very useful free tool by Microsoft) so I wanted to put all my assemblies into one directory and than merge them).

Here is VS command to do this:

copy "$(TargetPath)" "$(SolutionDir)\output\$(TargetFileName)"

paste this command in every projects post-build event and it's done.

It's using relative paths, so you don't have to worry about filling full directory and file names.


used macros:

  • $(TargetPath) - is full path of .dll file in current project
  • $(SolutionDir) - is solution directory :)
  • $(TargetFileName) - is name of .dll file


note:
you can easily discover these macros in post/pre build window by expanding <<Macros.