【问题标题】:How to write a code snippet to generate a method in C#?如何编写代码片段以在 C# 中生成方法?
【发布时间】:2012-09-02 03:06:28
【问题描述】:

我想写一个代码 sn-p 来做以下事情,比如如果我有一个类,比如说 MyClass:

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

所以 sn-p 应该创建以下方法:

 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;
    }

所以我的想法是,如果我为任何类调用 sn-p,它应该创建 DoUpdate 方法,并且应该按照我在上面示例中所做的方式编写所有属性。

所以我想知道:

  1. 上述方法可以吗?
  2. 如果是,我应该如何开始,有什么指导吗?

【问题讨论】:

  • 为什么不只使用一些 OOP 概念?
  • 有什么要求?您只是在寻找房产吗?你也想要静态属性吗?
  • 在性能等方面有什么要求?例如,编写基于反射的泛型 bool DoUpdate<T>(this T target, T source) 将非常容易 - 然后:不需要 sn-ps!

标签: c# code-snippets


【解决方案1】:

使用实用方法怎么样:

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;
    }
}

示例用法:

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);

请注意,如果要在紧密循环(等)中使用,这可能会得到极大的优化,但这样做需要元编程知识。

【讨论】:

  • 如果我在 MyClass 中有其他类型作为属性怎么办?
  • 这实际上是一个很好的解决方案,但是否也可以编写一个 sn-p 来做同样的事情?
  • @Praveen 定义“其他类型”; re sn-p - 我不知道
  • 问题是这个方法很慢,因为它使用反射,这就是为什么实例方法可以更好。
  • @praveen 就像我提到的:它可以通过元编程变得更快。此外,慢是相对的 - 对于大多数用途来说,它仍然足够快。
【解决方案2】:

你的 sn-ps 应该在

C:\Users\CooLMinE\Documents\Visual Studio(版本)\代码 片段\Visual C#\我的代码片段

获取现有 sn-p 并对其进行修改以避免重构文件布局的最简单方法。

这是您可以使用的模板:

<?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>

当您希望它根据类名等生成名称时,这应该会派上用场: http://msdn.microsoft.com/en-us/library/ms242312.aspx

【讨论】:

  • 我在这里提出了类似的建议stackoverflow.com/a/19247785/687441,但只是为了创建一个空方法。通常我会使用属性 sn-p (prop 或 propfull 其中 是键盘上的制表键)来创建属性,但如果它总是相同的代码您可以按照coolmine的建议对属性进行硬编码;不过不利于重复使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多