【问题标题】:Properties without 'property type' in C#C# 中没有“属性类型”的属性
【发布时间】:2011-07-03 11:47:28
【问题描述】:

我正在将 Delphi 代码转换为 C#。

我有一个复杂的类结构,其中一个类是其所有子类的主要'主干'

在 Delphi 中,我可以使用类型定义私有/受保护字段,并使用相同类型定义该字段的属性,而不再在子类中编写类型。

这是一个有点(和功能)的例子:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  Parent = class
  strict protected
    _myFirstField: Int64;
  public
    property MyFirstField: Int64    write _myFirstField;
  end;

  Child1 = class(Parent)
  public
    // Inherits the write/set behaviour..
    // And it doesn't need to define the type 'over and over' on all child classes.
    //
    // ******* Note MyFirstField here has not type.... ************
    property MyFirstField        read _myFirstField;  // Adding READ behaviour to the property.
  end;

var
  Child1Instance: Child1;
begin
    Child1Instance := Child1.Create;
    //Child1Instance.MyFirstField := 'An String';  <<-- Compilation error because type
    Child1Instance.MyFirstField := 11111;
    WriteLn(IntToStr(Child1Instance.MyFirstField));
    ReadLn;
end.

如您所见,我不需要一遍又一遍地定义属性类型。 如果以后需要更改var类型,只能在父类中更改。

有没有办法在 C# 中获得同样的行为?

【问题讨论】:

  • 请显示您在 C# 中尝试过的内容。按照通常的 OOP,您可以在基类中拥有一个受保护的属性,这将与 set/get 一起在子类中可用,并且当然保持其类型定义。
  • C#私有/受保护的属性行为不就是一模一样吗?
  • 真的,我必须恢复我想做的事情:我在祖先类中声明了所有可能的属性,我只想在子类上“发布”一组该属性。无需重新声明整个属性...既不是类型也不是访问者。
  • 不,C# 中没有模式可以提高派生类中成员的可见性。您需要像 Marc Gravell 的回答那样创建一个全新的属性。

标签: c# delphi c#-4.0 types accessor


【解决方案1】:

不,有。公共 API 上的类型必须是显式的。唯一不明确的是var,它仅限于方法变量。

此外,您不能更改 C# 中的签名(在子类中添加公共 getter) - 您必须重新声明它:

// base type 
protected string Foo {get;set;}

// derived type
new public string Foo {
    get { return base.Foo; }
    protected set { base.Foo = value; }
}

但正如new 所暗示的那样:这是一个不相关的属性,不需要具有相同的类型。

【讨论】:

  • 谢谢 Marc.... 然后我必须为“相同”的 Foo 属性重新编写所有行为,即使这种行为是相同的,不是吗? :-(
  • @FerPt 不,只是代理到base.,就像我的例子中一样
【解决方案2】:

据我了解,您可以这样做:

public class Parent
{
    protected Int64 MyCounter{ get; set; }
}

public class Child : Parent
{
    protected string ClassName 
   { 
        get 
        {
            return "Child";
        }
    }
}

public class Runner
{
    static void Main(string[] args)
    {
        var c = new Child();
        c.Counter++;

        Console.WriteLIne(c.Counter);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 2018-12-07
    • 2017-11-12
    • 2019-12-30
    相关资源
    最近更新 更多