How to write a code snippet to generate a method in C#?
Asked Answered
B

2

6

I want to write a code snippet which does following thing, like if I have a class let's say MyClass:

   class MyClass
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }

so the snippet should create following method:

 public bool DoUpdate(MyClass myClass)
  {
        bool isUpdated = false;
        if (Age != myClass.Age)
        {
            isUpdated = true;
            Age = myClass.Age;
        }
        if (Name != myClass.Name)
        {
            isUpdated = true;
            Name = myClass.Name;
        }
        return isUpdated;
    }

So the idea is if I call the snippet for any class it should create DoUpdate method and should write all the properties in the way as I have done in the above example.

So I want to know :

  1. Is it possible to do the above ?
  2. If yes how should I start, any guidance ?
Bunyip answered 1/9, 2012 at 18:51 Comment(3)
why do not use just some OOP concept?Poirier
What are the requirements? Are you only looking for properties? Do you want static properties as well?Paulownia
What are the requirements in terms of performance etc? It would be pretty easy to write a reflection based generic bool DoUpdate<T>(this T target, T source), for example - then: no snippets required!Cayser
C
1

How about a utility method instead:

public static class MyUtilities
{
    public static bool DoUpdate<T>(
        this T target, T source) where T: class
    {
        if(target == null) throw new ArgumentNullException("target");
        if(source == null) throw new ArgumentNullException("source");

        if(ReferenceEquals(target, source)) return false;
        var props = typeof(T).GetProperties(
            BindingFlags.Public | BindingFlags.Instance);
        bool result = false;
        foreach (var prop in props)
        {
            if (!prop.CanRead || !prop.CanWrite) continue;
            if (prop.GetIndexParameters().Length != 0) continue;

            object oldValue = prop.GetValue(target, null),
                   newValue = prop.GetValue(source, null);
            if (!object.Equals(oldValue, newValue))
            {
                prop.SetValue(target, newValue, null);
                result = true;
            }
        }
        return result;
    }
}

with example usage:

var a = new MyClass { Name = "abc", Age = 21 };
var b = new MyClass { Name = "abc", Age = 21 };
var c = new MyClass { Name = "def", Age = 21 };

Console.WriteLine(a.DoUpdate(b)); // false - the same
Console.WriteLine(a.DoUpdate(c)); // true - different

Console.WriteLine(a.Name); // "def" - updated
Console.WriteLine(a.Age);

Note that this could be optimized hugely if it is going to be used in a tight loop (etc), but doing so requires meta-programming knowledge.

Cayser answered 1/9, 2012 at 19:6 Comment(5)
What if I have other types in the MyClass as properties ?Bunyip
It's very good solution actually but is it also possible to write a snippet to do the same ?Bunyip
@Praveen define "other types"; re snippet - I have no ideaCayser
The problem is this method is very slow coz it's using reflection, that's why instance method could be better.Bunyip
@praveen like I mentioned: it could be made faster with meta-programming. Also, slow is relative - it will still be fast enough for most usages.Cayser
W
1

Your snippets should be under

C:\Users\CooLMinE\Documents\Visual Studio (version)\Code Snippets\Visual C#\My Code Snippets

The most easy way you be taking an existent snippet and modifying it to avoid reconstructing the layout of the file.

Here's a template you can work with:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>snippetTitle</Title>
            <Shortcut>snippetShortcutWhichYouWillUseInVS</Shortcut>
            <Description>descriptionOfTheSnippet</Description>
            <Author>yourname</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                </Literal>
                <Literal Editable="false">
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[yourcodegoeshere]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

This should come in handy when you want it to generate names based on the class name and so on: http://msdn.microsoft.com/en-us/library/ms242312.aspx

Wolcott answered 1/9, 2012 at 19:0 Comment(1)
I suggested something similar here https://mcmap.net/q/277626/-code-snippets-for-methods-in-visual-studio but only to create an empty method. Typically I'd use the property snippet (prop<tab><tab> or propfull<tab><tab> where <tab> is the tab key on your keyboard) to create the properties, but if it's always the same code you could hardcode the properties as coolmine suggested; not good for reuse though.Acidophil
C
1

How about a utility method instead:

public static class MyUtilities
{
    public static bool DoUpdate<T>(
        this T target, T source) where T: class
    {
        if(target == null) throw new ArgumentNullException("target");
        if(source == null) throw new ArgumentNullException("source");

        if(ReferenceEquals(target, source)) return false;
        var props = typeof(T).GetProperties(
            BindingFlags.Public | BindingFlags.Instance);
        bool result = false;
        foreach (var prop in props)
        {
            if (!prop.CanRead || !prop.CanWrite) continue;
            if (prop.GetIndexParameters().Length != 0) continue;

            object oldValue = prop.GetValue(target, null),
                   newValue = prop.GetValue(source, null);
            if (!object.Equals(oldValue, newValue))
            {
                prop.SetValue(target, newValue, null);
                result = true;
            }
        }
        return result;
    }
}

with example usage:

var a = new MyClass { Name = "abc", Age = 21 };
var b = new MyClass { Name = "abc", Age = 21 };
var c = new MyClass { Name = "def", Age = 21 };

Console.WriteLine(a.DoUpdate(b)); // false - the same
Console.WriteLine(a.DoUpdate(c)); // true - different

Console.WriteLine(a.Name); // "def" - updated
Console.WriteLine(a.Age);

Note that this could be optimized hugely if it is going to be used in a tight loop (etc), but doing so requires meta-programming knowledge.

Cayser answered 1/9, 2012 at 19:6 Comment(5)
What if I have other types in the MyClass as properties ?Bunyip
It's very good solution actually but is it also possible to write a snippet to do the same ?Bunyip
@Praveen define "other types"; re snippet - I have no ideaCayser
The problem is this method is very slow coz it's using reflection, that's why instance method could be better.Bunyip
@praveen like I mentioned: it could be made faster with meta-programming. Also, slow is relative - it will still be fast enough for most usages.Cayser

© 2022 - 2024 — McMap. All rights reserved.