在设计时,是否有办法在Visual Studio 2010中初始化具有所有属性的对象?

背景

我在VS 2010,.NET 4,C#中编​​写代码。 此外,如果重要,我使用的是最新版本的ReSharper。

假设我有这个模型:

public class SomeObject { public string Red{ get; set; } public string Green{ get; set; } public string Blue{ get; set; } public string Yellow{ get; set; } public string Purple{ get; set; } public string Orange{ get; set; } public string Black{ get; set; } } 

在代码的其他地方,我需要实例化其中一个对象,如下所示:

 SomeObject myObject = new SomeObject{ red = "some value", blue = "some other value", . . ., black="last value" }; 

* 注意: *我有时希望仅使用其总可能属性的一部分(即红色和蓝色)初始化此对象。

目前,我必须为SomeObject每个新实例输入每个属性(红色,蓝色,绿色等)。 VS2010中是否有热键或其他东西预先填充了这些属性,所以我只需要为每个属性分配值而不是键入每个属性?

目前,我必须为SomeObject的每个新实例输入每个属性(红色,蓝色,绿色等)。

就个人而言,如果你需要为每个对象实例设置这些,我会通过添加一个获取所有参数的构造函数来处理这个问题,而不是使用对象初始化语法。 这将为您提供完整的智能感知,但也可以帮助/强制您每次都正确构建对象。

请记住,类型的构造函数应该强制您提供将对象正确初始化为正确状态所需的所有参数。 对象初始化器的一个缺点是它们不会在编译时强制执行此操作。 因此,如果每个对象实例都需要所有这些属性,则构造函数应提供它们而不是使用对象初始值设定项。

您可以使用智能代码完成。

写:new SomeObject {

然后按Ctrl + Alt + Space: – >工具提示窗口中列出了所有可能的属性

然后选择一个属性(即’Red’)并按ENTER – > new SomeObject {Red =}

然后输入“,”再按一次Ctrl + Alt + Space,选择下一个属性,依此类推。

所有属性是否始终相同? 为什么不在已经设置的位置添加构造函数? 或者不止一个。

看一下Code Snippets。 我想这会给你你想要的东西。

一般没有键盘快捷方式来准备对象初始化程序。

VS IDE或Reshaper无法对要设置属性的值进行合理的猜测,因此必须插入无效或最好的次优代码。

你可以实现一个特定的解决方案,正如其他答案所暗示的那样,如果你发现自己这样做,建设者可能会走的路,但我不相信这是你的问题。

你真的想要读/写的颜色吗? 如果没有,这是最简单的解决方案:

 public class SomeObject { public const string Red = "red"; public const string Green = "green"; public const string Blue = "blue"; ... } 

但是,如果您希望更灵活,并且只能初始化某些属性,则可以使用对象初始化语法。 使用原始的SomeObject实现,您可以创建一个新对象:

 var obj = new SomeObject { Red = "red", Blue = "blue" }; 

我已经创建了一个VS宏来执行此操作。 我的主要用途是为我的DTO生成虚拟测试数据。

你写了一句话:

 var x = new SomeType(); 

然后宏将为每个可写属性/成员生成一行

 x.IntProperty = 0; x.StringProperty = "StringProperty"; x.DateProperty = new DateTime(2012, 1, 31); x.SomeIntList = new List(); x.SomeTypeProperty = new SomeType(); 

(你当然可以在最后一行重新运行宏来生成x.SomeTypeProperty.Y = 0等)

 Option Explicit On Option Strict On Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Collections.Generic Imports System.Linq Imports System.Text.RegularExpressions Imports System.Windows.Forms Friend Module InitializeAllMembers Public DTE As EnvDTE80.DTE2 Private ReadOnly _usings As New HashSet(Of String) Sub InitializeAllMembers(ByVal getValue As Boolean) Try Dim memberAssignment As Func(Of String, String, String, EnvDTE.CodeTypeRef, String) = Nothing Dim selection As EnvDTE.TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection) Dim editPoint As EditPoint = selection.BottomPoint.CreateEditPoint editPoint.StartOfLine() Dim className As String = "" Dim indent As String = "" Dim variable As String = "" Dim parseError As String If DTE.ActiveDocument.ProjectItem Is Nothing Then MessageBox.Show("File does not belong to a project") End If If DTE.ActiveDocument.Language = "Basic" Then parseError = GetVbInitialization(editPoint.GetText(editPoint.LineLength), className, indent, variable) If getValue Then memberAssignment = AddressOf VbMemberGetValue Else memberAssignment = AddressOf VbMemberAssignment End If ElseIf DTE.ActiveDocument.Language = "CSharp" Then parseError = GetCSharpInitialization(editPoint.GetText(editPoint.LineLength), className, indent, variable) If getValue Then memberAssignment = AddressOf CSharpMemberGetValue Else memberAssignment = AddressOf CSharpMemberAssignment End If Else parseError = "Not supported language " & DTE.ActiveDocument.Language End If If parseError IsNot Nothing Then MessageBox.Show(parseError) Exit Sub End If Dim currentFunction As CodeElement = FindCodeElement(selection.ActivePoint, DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElements) If currentFunction Is Nothing Then MessageBox.Show("Can't find current function") Exit Sub End If _usings.Clear() FindAllUsings(currentFunction) Dim classType As CodeElement = DTE.Solution.Projects.Cast(Of Project) _ .Select(Function(x) FindClassInProjectItems(x.ProjectItems, className)) _ .FirstOrDefault(Function(x) x IsNot Nothing) If classType Is Nothing Then MessageBox.Show("Can't find type in solution: " & className) Exit Sub End If DTE.UndoContext.Open("InitializeAllMembers") PrintMemberAssignments(memberAssignment, editPoint, indent, variable, GetMembers(classType)) If TypeOf classType Is CodeClass Then For Each base As CodeElement In CType(classType, CodeClass).Bases If TypeOf base Is CodeClass Then PrintMemberAssignments(memberAssignment, editPoint, indent, variable, GetMembers(base)) End If Next End If DTE.UndoContext.Close() Catch objException As System.Exception MessageBox.Show(objException.Message) End Try End Sub Private Function GetVbInitialization(ByVal line As String, _ ByRef className As String, _ ByRef indent As String, _ ByRef variable As String) As String Dim vbinitialization As New Regex("(?\s*)Dim\s+(?[\S=]+)\s+(?:As\s+(?:New\s+)?(?[^\s\(]+))?(?:\s*=\s*New\s+(?[^\s\(]+))?", _ RegexOptions.IgnoreCase) Dim match As Match = vbinitialization.Match(line) If Not match.Success Then Return "No assignment on row" End If Dim foundDeclaredType As Boolean = match.Groups("DeclaredType").Success Dim foundCreatedType As Boolean = match.Groups("CreatedType").Success If Not (foundDeclaredType OrElse foundCreatedType) Then Return "Can't find type on row" End If className = If(foundDeclaredType, match.Groups("DeclaredType"), match.Groups("CreatedType")).Value indent = match.Groups("Indent").Value variable = match.Groups("VariableName").Value Return Nothing End Function Private Function GetCSharpInitialization(ByVal line As String, _ ByRef className As String, _ ByRef indent As String, _ ByRef variable As String) As String Dim csharpinitialization As New Regex("(?\s*)(?:(?\S+)\s+)?(?[\S=]+)\s*=\s*(?new)?\s*(?[^\s\(]+)") Dim match As Match = csharpinitialization.Match(line) If Not match.Success Then Return "No assignment on row" End If Dim foundDeclaredType As Boolean = match.Groups("DeclaredType").Success AndAlso match.Groups("DeclaredType").Value <> "var" Dim foundCreatedType As Boolean = match.Groups("new").Success If Not (foundDeclaredType OrElse foundCreatedType) Then Return "Can't find type on row" End If className = If(foundDeclaredType, match.Groups("DeclaredType"), match.Groups("CreatedType")).Value indent = match.Groups("Indent").Value variable = match.Groups("VariableName").Value Return Nothing End Function Sub FindAllUsings(ByVal elem As Object) If TypeOf elem Is CodeFunction Then FindAllUsings(CType(elem, CodeFunction).Parent) ElseIf TypeOf elem Is CodeClass Then _usings.Add(CType(elem, CodeClass).FullName) FindAllUsings(CType(elem, CodeClass).Parent) ElseIf TypeOf elem Is CodeStruct Then _usings.Add(CType(elem, CodeStruct).FullName) FindAllUsings(CType(elem, CodeStruct).Parent) ElseIf TypeOf elem Is CodeNamespace Then _usings.Add(CType(elem, CodeNamespace).FullName) For Each ns As String In CType(elem, CodeNamespace).Members.OfType(Of CodeImport) _ .Select(Function(x) x.Namespace) _usings.Add(ns) Next FindAllUsings(CType(elem, CodeNamespace).Parent) ElseIf TypeOf elem Is FileCodeModel Then For Each ns As String In CType(elem, FileCodeModel).CodeElements.OfType(Of CodeImport) _ .Select(Function(x) x.Namespace) _usings.Add(ns) Next End If End Sub Public Function FindCodeElement(ByVal caretPosition As TextPoint, ByVal elems As CodeElements) As CodeElement If elems Is Nothing Then Return Nothing Return elems.Cast(Of CodeElement) _ .Where(Function(x) x.StartPoint.LessThan(caretPosition) AndAlso _ x.EndPoint.GreaterThan(caretPosition)) _ .Select(Function(x) If(FindCodeElement(caretPosition, GetMembers(x)), x)) _ .FirstOrDefault() End Function Public Sub PrintMemberAssignments(ByVal memberAssignment As Func(Of String, String, String, CodeTypeRef, String), _ ByVal editPoint As EditPoint, _ ByVal indent As String, _ ByVal variable As String, _ ByVal members As CodeElements) For Each member As CodeElement In members Dim typeref As EnvDTE.CodeTypeRef If TypeOf member Is CodeProperty2 Then Dim prop As CodeProperty2 = CType(member, CodeProperty2) If prop.Setter Is Nothing Then If prop.Access <> vsCMAccess.vsCMAccessPublic Then Continue For If prop.ReadWrite = vsCMPropertyKind.vsCMPropertyKindReadOnly Then Continue For If prop.IsShared Then Continue For ElseIf prop.Setter.Access <> vsCMAccess.vsCMAccessPublic Then Continue For ElseIf prop.Setter.IsShared Then Continue For End If typeref = prop.Type ElseIf TypeOf member Is CodeVariable Then Dim var As CodeVariable = CType(member, CodeVariable) If var.Access <> vsCMAccess.vsCMAccessPublic Then Continue For If var.IsConstant Then Continue For If var.IsShared Then Continue For typeref = var.Type Else Continue For End If editPoint.EndOfLine() editPoint.Insert(ControlChars.NewLine) editPoint.Insert(memberAssignment(indent, variable, member.Name, typeref)) Next End Sub Private Function TrimKnownNamespace(ByVal fullName As String) As String Return fullName.Substring(_usings.Where(Function(x) fullName.StartsWith(x) AndAlso _ fullName.Length > x.Length AndAlso _ fullName(x.Length) = "."c) _ .Select(Function(x) x.Length + 1) _ .DefaultIfEmpty(0) _ .Max()) End Function Private Function FindClassInProjectItems(ByVal nprojectItems As ProjectItems, ByVal classname As String) As CodeElement If nprojectItems Is Nothing Then Return Nothing For Each nprojectitem As ProjectItem In nprojectItems Dim found As CodeElement If nprojectitem.Kind = EnvDTE.Constants.vsProjectItemKindPhysicalFile Then If nprojectitem.FileCodeModel Is Nothing Then Continue For found = FindClassInCodeElements(nprojectitem.FileCodeModel.CodeElements, classname) If found IsNot Nothing Then Return found End If If nprojectitem.SubProject IsNot Nothing Then found = FindClassInProjectItems(nprojectitem.SubProject.ProjectItems, classname) If found IsNot Nothing Then Return found End If found = FindClassInProjectItems(nprojectitem.ProjectItems, classname) If found IsNot Nothing Then Return found Next Return Nothing End Function Private Function FindClassInCodeElements(ByVal elems As CodeElements, ByVal classname As String) As CodeElement If elems Is Nothing Then Return Nothing For Each elem As CodeElement In elems If IsClassType(elem) Then If classname = elem.Name Then Return elem ElseIf Not TypeOf elem Is CodeNamespace Then Continue For End If If _usings.Contains(elem.FullName) Then Dim found As CodeElement = FindClassInCodeElements(GetMembers(elem), classname) If found IsNot Nothing Then Return found End If Next Return Nothing End Function Private Function GetMembers(ByVal elem As CodeElement) As CodeElements If TypeOf elem Is CodeClass Then Return CType(elem, CodeClass).Members ElseIf TypeOf elem Is CodeNamespace Then Return CType(elem, CodeNamespace).Members ElseIf TypeOf elem Is CodeStruct Then Return CType(elem, CodeStruct).Members ElseIf TypeOf elem Is CodeInterface Then Return CType(elem, CodeInterface).Members End If Return Nothing End Function Private Function IsClassType(ByVal elem As CodeElement) As Boolean Return TypeOf elem Is CodeClass OrElse TypeOf elem Is CodeStruct OrElse TypeOf elem Is CodeInterface End Function Private Function CSharpMemberAssignment(ByVal indent As String, _ ByVal variable As String, _ ByVal membername As String, _ ByVal typeref As EnvDTE.CodeTypeRef) As String Dim typekind As EnvDTE.vsCMTypeRef = typeref.TypeKind Dim value As String If typekind = vsCMTypeRef.vsCMTypeRefArray Then value = "{0}{1}.{2} = new {3}[1];" Return String.Format(value, indent, variable, membername, TrimKnownNamespace(typeref.ElementType.AsString)) & _ ControlChars.NewLine & _ CSharpMemberAssignment(indent, variable, membername & "[0]", typeref.ElementType) ElseIf typekind = vsCMTypeRef.vsCMTypeRefBool Then value = "false" ElseIf typekind = vsCMTypeRef.vsCMTypeRefChar Then value = "'x'" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDecimal Then value = "0.00m" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDouble Then value = "0.00" ElseIf typekind = vsCMTypeRef.vsCMTypeRefInt Then value = "0" ElseIf typekind = vsCMTypeRef.vsCMTypeRefLong Then value = "0" ElseIf typekind = vsCMTypeRef.vsCMTypeRefShort Then value = "0" ElseIf typekind = vsCMTypeRef.vsCMTypeRefByte Then value = "0" ElseIf typekind = vsCMTypeRef.vsCMTypeRefString Then value = """" & membername & """" ElseIf typekind = vsCMTypeRef.vsCMTypeRefCodeType AndAlso _ typeref.AsString = "System.DateTime" Then value = String.Format("new DateTime({0:yyyy}, {0:%M}, {0:%d})", DateTime.Today) Else value = "new " & TrimKnownNamespace(typeref.AsString) & "()" End If Return String.Format("{0}{1}.{2} = {3};", indent, variable, membername, value) End Function Private Function CSharpMemberGetValue(ByVal indent As String, _ ByVal variable As String, _ ByVal membername As String, _ ByVal typeref As EnvDTE.CodeTypeRef) As String Dim typekind As EnvDTE.vsCMTypeRef = typeref.TypeKind Dim value As String If typekind = vsCMTypeRef.vsCMTypeRefArray Then value = "{0}{1}.{2} = new {3}[1];" Return String.Format(value, indent, variable, membername, TrimKnownNamespace(typeref.ElementType.AsString)) & _ ControlChars.NewLine & _ CSharpMemberGetValue(indent, variable, membername & "[0]", typeref.ElementType) ElseIf typekind = vsCMTypeRef.vsCMTypeRefBool Then value = "src.GetBoolean()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefChar Then value = "src.GetChar()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDecimal Then value = "src.GetDecimal()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDouble Then value = "src.GetDouble()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefInt Then value = "src.GetInt32()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefLong Then value = "src.GetInt64()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefShort Then value = "src.GetInt16()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefByte Then value = "src.GetByte()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefString Then value = "src.GetString()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefCodeType AndAlso _ typeref.AsString = "System.DateTime" Then value = "src.GetDateTime()" Else value = "new " & TrimKnownNamespace(typeref.AsString) & "()" End If Return String.Format("{0}{1}.{2} = {3};", indent, variable, membername, value) End Function Private Function VbMemberAssignment(ByVal indent As String, _ ByVal variable As String, _ ByVal membername As String, _ ByVal typeref As EnvDTE.CodeTypeRef) As String Dim typekind As EnvDTE.vsCMTypeRef = typeref.TypeKind Dim value As String If typekind = vsCMTypeRef.vsCMTypeRefArray Then value = "{0}Redim {1}.{2}(1)" ' Vb don't need type argument Return String.Format(value, indent, variable, membername, TrimKnownNamespace(typeref.ElementType.AsString)) & _ ControlChars.NewLine & _ VbMemberAssignment(indent, variable, membername & "(0)", typeref.ElementType) ElseIf typekind = vsCMTypeRef.vsCMTypeRefBool Then value = "False" ElseIf typekind = vsCMTypeRef.vsCMTypeRefChar Then value = """x""c" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDecimal Then value = "0.00d" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDouble Then value = "0.00r" ElseIf typekind = vsCMTypeRef.vsCMTypeRefInt Then value = "0" ElseIf typekind = vsCMTypeRef.vsCMTypeRefLong Then value = "0L" ElseIf typekind = vsCMTypeRef.vsCMTypeRefShort Then value = "0s" ElseIf typekind = vsCMTypeRef.vsCMTypeRefByte Then value = "0 AS Byte" ElseIf typekind = vsCMTypeRef.vsCMTypeRefString Then value = """" & membername & """" ElseIf typekind = vsCMTypeRef.vsCMTypeRefArray Then value = "New " & TrimKnownNamespace(typeref.ElementType.AsString) & "(1)" ElseIf typekind = vsCMTypeRef.vsCMTypeRefCodeType AndAlso _ typeref.AsString = "Date" Then value = String.Format("new Date({0:yyyy}, {0:%M}, {0:%d})", DateTime.Today) Else value = "new " & TrimKnownNamespace(typeref.AsString) & "()" End If Return String.Format("{0}{1}.{2} = {3}", indent, variable, membername, value) End Function Private Function VbMemberGetValue(ByVal indent As String, _ ByVal variable As String, _ ByVal membername As String, _ ByVal typeref As EnvDTE.CodeTypeRef) As String Dim typekind As EnvDTE.vsCMTypeRef = typeref.TypeKind Dim value As String If typekind = vsCMTypeRef.vsCMTypeRefArray Then value = "{0}Redim {1}.{2}(1)" ' Vb don't need type argument Return String.Format(value, indent, variable, membername, TrimKnownNamespace(typeref.ElementType.AsString)) & _ ControlChars.NewLine & _ VbMemberGetValue(indent, variable, membername & "(0)", typeref.ElementType) ElseIf typekind = vsCMTypeRef.vsCMTypeRefBool Then value = "src.GetBoolean()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefChar Then value = "src.GetChar()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDecimal Then value = "src.GetDecimal()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefDouble Then value = "src.GetDouble()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefInt Then value = "src.GetInt32()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefLong Then value = "src.GetInt64()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefShort Then value = "src.GetInt16()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefByte Then value = "src.GetByte()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefString Then value = "src.GetString()" ElseIf typekind = vsCMTypeRef.vsCMTypeRefArray Then value = "New " & TrimKnownNamespace(typeref.ElementType.AsString) & "(1)" ElseIf typekind = vsCMTypeRef.vsCMTypeRefCodeType AndAlso _ typeref.AsString = "Date" Then value = "src.GetDateTime()" Else value = "new " & TrimKnownNamespace(typeref.AsString) & "()" End If Return String.Format("{0}{1}.{2} = {3}", indent, variable, membername, value) End Function End Module 

早上好,您应该可以通过创建Visual Studio代码段或创建ReSharper代码模板来实现此目的