65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual Studio .NET 中从类变量生成属性的插件

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.89/5 (9投票s)

2009年12月23日

CPOL

2分钟阅读

viewsIcon

40872

downloadIcon

723

用于自动生成属性(Getter 和 Setter)的 Visual Studio 2008 插件。

以前

Before

操作后

After

引言

在 Visual Studio (VS) 中,您必须逐个手动输入或生成属性。 如果您有很多变量,这将非常繁琐。 此属性生成器管理属性的创建和修改。 因此,如果您有十个变量,并使用代码片段,则您必须调用它十次。 使用属性生成器,您可以在一次操作中生成所有您选择的变量。

背景

在本文中,我假设您了解开发插件的基础知识。 如果您不了解这些基础知识,可以阅读 这篇文章

Using the Code

要使用,*.AddIn*.dll 必须存在于 My Documents\Visual Studio 2008\Addins

  • ClassField.cs 是一个小类,用于包含关于变量和该变量属性的信息。
  • ClassManager.cs 用于检索类、变量和编写属性。
  • ClassStruct 包含接口 Istruct,此接口封装了 CodeClassCodeStructCodeClass 是一个 VS 对象,包含有关 Class 的信息,而 CodeStruct 则包含有关 Struct 的信息。

ClassManager

这个类的构造函数接受一个 DTE2,它是 Visual Studio 的一个对象。 有了此对象,我们可以在活动文档中检索所有代码元素 (Namespace, Class, ...)。 为此,我们使用两种方法,ProcessElement LoadClass

ProcessElement(CodeElement elem) 是一种递归方法,用于查找活动文档中存在的 Class Struct 。 我们可以使用此属性 kind 知道元素的类型。 找到的 Class Struct 被存储在 m_Classes 中。 它用于将 combobox 与所有类名绑定。 当 combobox 更改时,我们调用方法 LoadClass(IStruct mclass)

LoadClass(Istruct mclass) 检索 mclass 及其基类中存在的变量和属性。 此方法返回一个 ClassField 列表,用于创建 treeview

private bool LoadClasses()
{
    m_Classes = new List<IStruct>();
    if (((this.m_applicationObject.ActiveDocument == null) || 
	(this.m_applicationObject.ActiveDocument.ProjectItem == null)) || 
	((this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel == null) || 
	(this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements 
								== null)))
    {
        return false;
    }
    else
    {
        foreach (CodeElement element in 
	this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements)
        {
            this.ProcessElement(element);
        }
    }
    return true;
}

/// <summary>
/// Retrieve all 'class' and 'struct' in the active document
/// </summary>
/// <param name="elem"></param>
/// <param name="rootName"></param>
private void ProcessElement(CodeElement elem)
{
    if (elem.Kind == vsCMElement.vsCMElementNamespace)
    {
        CodeNamespace namespac = elem as CodeNamespace;
        foreach (CodeElement element in namespac.Members)
        {
            this.ProcessElement(element);
        }
    }
    else if (elem.Kind == vsCMElement.vsCMElementClass)
    {
        ClassStructure item = new ClassStructure(elem as CodeClass);
        this.m_Classes.Add(item);
        foreach (CodeElement element2 in item.Members)
        {
            this.ProcessElement(element2);
        }
    }
    else if (elem.Kind == vsCMElement.vsCMElementStruct)
    {
        StructStructure struct3 = new StructStructure(elem as CodeStruct);
        this.m_Classes.Add(struct3);
    }
}  

为了编写或删除属性,我们使用 EditPoint,这是一个用于操作文本的 VS 对象。 但是,在此之前,如果属性不存在,我们使用 m_currentStructure.AddProperty 创建它。 m_currentStructure 是当前的 IstructAddProperty 方法创建一个新的属性代码结构并将代码插入到正确的位置。 对于位置,如果它是 CodeElement,则在它之后创建属性,0 在开始处创建新元素,而 -1 在末尾创建新元素。 但是此属性是空的,我们检索属性的起始点 (get set) 和结束点,并删除此选择 point.Delete(point2); 在删除空属性之后,我们编写我们的属性 point.Insert(field.GetMethod)。 如果属性已经存在,我们插入一个新行并编写我们想要的属性 (get set)。

要删除属性,我们选择属性的起始点和结束点,之后我们删除选择

public void WriteProperty(ClassField field, bool createGet, 
	bool createSet,bool setIsInternal, object position)
{
    CodeProperty property;
    //if null, create a new property else modify
    if (field.Property == null)
    {
        property = this.m_currentStructure.AddProperty
		(field, createGet, createSet, position);
        //Create summary
        EditPoint pt = property.StartPoint.CreateEditPoint();
        pt.LineUp(1);
        pt.Insert(string.Format(@"
/// <summary>
/// {0}{1}{2}
/// </summary>",
           createGet ? "Gets" : string.Empty,
           createSet && createGet ? "/" : string.Empty,
           createSet ? "Sets" : string.Empty));
           
        if (createGet)
        {
            property.Getter.IsShared = field.Field.IsShared;
            EditPoint point = property.Getter.StartPoint.CreateEditPoint();
            EditPoint point2 = property.Getter.EndPoint.CreateEditPoint();
            point.Delete(point2);
            point.Insert(field.GetMethod);
        }
        if (createSet)
        {
            property.Setter.IsShared = field.Field.IsShared;
            EditPoint point = property.Setter.StartPoint.CreateEditPoint();
            EditPoint point2 = property.Setter.EndPoint.CreateEditPoint();
            point.Delete(point2);
            point.Insert(field.SetMethod(setIsInternal));
        }
    }
    else
    {
        property = field.Property;
        if (createGet)
        {
            EditPoint point = property.Getter.EndPoint.CreateEditPoint();
            point.Insert(Environment.NewLine);
            point.Insert(field.GetMethod);
            EditPoint point2 = property.StartPoint.CreateEditPoint();
            EditPoint point3 = property.EndPoint.CreateEditPoint();
            point2.SmartFormat(point3);                
        }
        if (createSet)
        {
            EditPoint point = property.Getter.EndPoint.CreateEditPoint();
            point.Insert(Environment.NewLine);
            point.Insert(field.SetMethod(setIsInternal) );
            EditPoint point2 = property.StartPoint.CreateEditPoint();
            EditPoint point3 = property.EndPoint.CreateEditPoint();
            point2.SmartFormat(point3);               
        }
    }
}
class ClassField
{
     	public string GetMethod
         {
            get
            {
                return string.Format("get {{ return {0}{1}; }}",
		this.m_Field.IsShared ? "" : "this.", this.m_Field.Name);
            }
         }

	public string SetMethod(bool isInternal)
         {
                return string.Format("{2}  set {{ {0}{1} = value; }}", 
		this.m_Field.IsShared ? "" : "this.", this.m_Field.Name, isInternal ? 
		"internal" : string.Empty );
         }
}

历史

  • 2009 年 12 月 22 日 - 版本 1.0
© . All rights reserved.