添加属性的默认实现

时间:2016-05-20 09:52:05

标签: c# properties

我得到了以下课程:

public class Foo
{
    public string Property1
    {
        get { return (string)Properties["property1"]; }
        set { Properties.Add("property1", value); }
    }
    public string Property2
    {
        get { return (string)Properties["property2"]; }
        set { Properties.Add("property2", value); }
    }

    //A lot more here

    public string Property30
    {
        get { return (string)Properties["property30"]; }
        set { Properties.Add("property30", value); }
    }

    public string Property31
    {
        get { return (string)Properties["property31"]; }
        set { Properties.Add("property31", value); }
    }

    public Dictionary<string, object> Properties { get; set; } 
}

我正在复制getter和setter很多次,这是一种麻烦这个类有大约20/30属性。有没有办法自动实现这一点。我已经通过使Foo动态化并实现TryGetMember来完成实现,但我不喜欢对象不再强类型化(特别是在visual studio中没有自动完成的事实)。

干杯

2 个答案:

答案 0 :(得分:4)

如果您使用的是Visual Studio,则可以使用snippets。对于属性,默认情况下这些属性可用。 enter image description here

您还可以使用工具/代码段管理器create your own或导入其他开发人员或第三方制作的代码段。

这就是您的代码段大致如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>myprop</Title>
            <Shortcut>myprop</Shortcut>
            <Description></Description>
            <Author>Me</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Property type</ToolTip>
                    <Default>int</Default>
                </Literal>
                <Literal>
                    <ID>property</ID>
                    <ToolTip>Property name</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
                <Literal>
                    <ID>field</ID>
                    <ToolTip>The variable backing this property</ToolTip>
                    <Default>myVar</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[private $type$ $field$;

    public $type$ $property$
    {
        get { return ($type$)Properties["$field$"];}
        set { Properties.Add("$field$",value);}
    }
    $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

答案 1 :(得分:1)

我会使用PostSharp发布替代方案。免费版本适用于此示例。首先从nuget安装PostSharp,然后创建简单的方面:

[Serializable]
public class FooAspect : LocationInterceptionAspect {
    public override void OnGetValue(LocationInterceptionArgs args) {
        var foo = ((Foo)args.Instance);
        if (foo.Properties == null || !foo.Properties.ContainsKey(args.LocationName))
            args.Value = null;
        else
            args.Value = foo.Properties[args.LocationName];
    }

    public override void OnSetValue(LocationInterceptionArgs args) {
        var foo = ((Foo) args.Instance);
        if (foo.Properties == null)
            foo.Properties = new Dictionary<string, object>();
        foo.Properties[args.LocationName] = args.Value;
    }
}

这里我们基本上拦截属性的getter和setter并重写它们以使用Properties字典而不是之前的字典。然后将方面应用于Foo类(记得排除Properties属性本身以避免堆栈溢出):

[FooAspect(AttributeTargetMembers = "Property*")]
public class Foo
{        
    public string Property1 { get; set; }    
    public string Property2 { get; set; }
    public string Property30 { get; set; }
    public string Property31 { get; set; }

    public Dictionary<string, object> Properties {get; set; }
}

当然,仅为此使用PostSharp 是一种矫枉过正,但您可能会发现它在许多其他情况下也很有用。