【问题标题】:C# implement similar properties within a class using a "template"C# 使用“模板”在类中实现类似的属性
【发布时间】:2013-02-23 19:51:14
【问题描述】:

我一直想知道 - 在 c# 中是否有一种方法可以为类中的多个属性定义“模板”。这就是我的意思: 假设我有以下课程

class MyCLass
{
    public int  IntVal1 { get {...}; set{...} }
    public byte IntVal2 { get {...}; set{...} }
    ....
    public long IntValN { get {...}; set{...} }
}

我没有在 get 和 set 访问器中编写任何特定的实现,但我的想法是所有这些属性都有非常相似的实现 - 不同之处可能在于它们对具有不同类型的类的不同成员进行操作,但作为整体他们看起来都一样。

我的想法是找到一种方法来定义某种(让我们称之为)带有一些参数的“模板”,这些参数可能用于声明所有这些属性,而无需编写每个属性的实际实现他们-也许使用属性!?!

我猜我需要的类似于 C 宏。

提前 10 倍

【问题讨论】:

  • 10 x 什么提前?
  • 是……亲吻吗? *亲吻*

标签: c# generics properties macros


【解决方案1】:

是的,如果我理解正确的话,在 C# 中我们为此使用泛型:

class MyCLass<T>
{
    public T Val { get {...}; set{...} }
}

T 定义了你想要“模板化”的类型。

然后你可以像这样使用这个类:

var myClassInt = new MyClass<int>();
myClassInt.Val // is an integer

【讨论】:

  • 据我了解,他想“模板化”实现,而不是类型定义。
  • @LuisFilipe “不同之处可能在于它们对具有不同类型的类的不同成员进行操作,但总的来说它们看起来都相似。” - 不确定这是否意味着泛型。
  • 这是路易斯说的。换句话说:我正在寻找一种方法来为我的类中“相似”的所有属性创建一个基本实现,然后根据该“基本属性”模板定义这些属性中的每一个。
【解决方案2】:

您可以查看T4 templates 并从中生成代码:http://msdn.microsoft.com/en-us/library/vstudio/bb126445.aspx

如果您使用部分类,您可以将一个用于生成的代码,另一个用于非生成的代码。

这是一个很好的教程:http://t4-editor.tangible-engineering.com/How-Do-I-With-T4-Editor-Text-Templates.html

【讨论】:

  • 得详细看文章,不过我初步的理解是那些T4模板可以用来自动创建必要的代码(基于预定义的模板)。我的意思是,C# 本身是否支持通过定义一个通用的“模板”并将其“附加”到每个属性来构建具有类似实现的属性(在我的情况下)。
  • T4 模板可以定义通用的“模板”并在任何类型的配置文件上运行,然后可以作为“附加”部分。这就是实体框架如何根据类的某些配置生成所需的代码。 T4 是创建代码/执行宏工作的建议方法,在许多技术/框架中都可以找到。或许您可以就您想要实现的属性实现类型提供更具体的细节?
【解决方案3】:

简短的回答是“不”,但您可以采取一些措施来减少重复。例如,考虑:

private bool SetField<T>(ref T field, T value,
    [CallerMemberName] string memberName = null)
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        var handler = PropertyChanged;
        if (handler != null) handler(this,
            new PropertyChangedEventArgs(memberName));
        return true;
    }
    return false;
}

可以通过以下方式减少开销:

private string bar;
public string Bar
{
    get { return bar; }
    set { SetField(ref bar, value); }
}

【讨论】:

  • 是的,这就是我最终的结果。只是想我会检查替代方案。
【解决方案4】:

你需要在基类中有一个虚拟的受保护方法。此方法将设置属性。在子类中,您可以继承基本实现或覆盖 Init/Set/Get 方法并进行自定义实现。

abstract class BaseMyClass
{
    public BaseMyClass(arg1, arg2,...)
    {
        Init(arg1, arg2,...);
    }

    public int  IntVal1 { get {...}; set{...} }
    public byte IntVal2 { get {...}; set{...} }
    public byte IntVal3 
    { 
        get 
        {
            return GetIntVal3(); 
        } 
        set
        {
            SetIntVal3(value);
        }
    }

    protected void virtual Init(arg1, arg2,...)
    {
         //Init properties
    }

    protected virtual byte GetIntVal3()
    {
         //Implementation
    }

    protected virtual void SetIntVal3(value)
    {
         //Implementation
    }
}

class MyCLass : BaseMyClass
{
    public MyCLass(arg1, arg2, ...): base(arg1, arg2,...)
}

class AnotherMyCLass : BaseMyClass
{
    public MyCLass(arg1, arg2, ...): base(arg1, arg2,...)

    protected override void Init(arg1, arg2,...)
    {
         //Init properties
    }
}

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 2021-06-15
    • 2014-11-02
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 2019-07-11
    相关资源
    最近更新 更多