5

有没有办法classmethod在 C# 中执行 Python 中的操作?

也就是说,一个静态函数将根据使用它的任何子类将 Type 对象作为(隐式)参数。

我想要的一个例子大约是

class Base:
    @classmethod
    def get(cls, id):
        print "Would instantiate a new %r with ID %d."%(cls, id)

class Puppy(Base):
    pass

class Kitten(Base):
    pass

p = Puppy.get(1)
k = Kitten.get(1)

预期的输出是

Would instantiate a new <class __main__.Puppy at 0x403533ec> with ID 1.
Would instantiate a new <class __main__.Kitten at 0x4035341c> with ID 1.

(这里的键盘上的代码相同。)

4

5 回答 5

3

我想你想看看泛型。

MSFT 指南:

http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx

于 2010-01-13T17:37:03.667 回答
2

根据上下文,您需要泛型或虚拟方法。

于 2010-01-14T02:36:41.750 回答
2

原则上,你可以这样写:

class Base
{
    public static T Get<T>(int id)
        where T : Base, new()
    {
        return new T() { ID = id };
    }

    public int ID { get; set; }
}

然后你就可以写了var p = Base.Get<Puppy>(10)。或者,如果你感到受虐,你可以写Puppy.Get<Puppy>(10),甚至Kitty.Get<Puppy>;) 在所有情况下,你必须显式地传递类型,而不是隐式地传递。

或者,这也有效:

class Base<T> where T : Base<T>, new()
{
    public static T Get(int id)
    {
        return new T() { ID = id };
    }

    public int ID { get; set; }
}

class Puppy : Base<Puppy>
{
}

class Kitten : Base<Kitten>
{
}

您仍然需要将类型传递回基类,这样您就可以Puppy.Get(10)按预期编写。

var p = new Puppy(10)但是,当它同样简洁和惯用时,有理由这样写吗?可能不是。

于 2010-01-15T09:07:42.817 回答
0

这相当于 Object Pascal 中的类方法。(.Net 实现将是 RemObject 的氧气)。

然而,虽然类引用和虚拟类方法或看似静态的方法可以访问某些类级状态在原始平台上很好,但我认为它们对 .Net 或 C# 没有多大意义。

我曾经也在 Oxygene 中编程了好几年,而且我从不需要类引用。

不是因为我不知道如何使用它们。在“原始”的 ObjectPascal 平台,原生 Delphi 中,我一直使用它们。但是因为.Net和BCL对它们没有真正的支持,所以使用它们没有任何优势。而像 python 或本机 Delphi 这样的平台确实在其库中支持它们。

您显然不想要静态方法,您想要的是可以具有状态和/或支持继承的东西。因此,无论是工厂,还是在您的情况下,构造函数都可以。

于 2010-01-15T09:17:06.463 回答
0

Puppy.get()因为 C# 是静态编译的,所以在编译时解析对的调用,例如。众所周知Base.get(),这意味着生成的 CIL(通用中间语言)将有一个调用指令Base.get()

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       9 (0x9)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldc.i4.1
  IL_0002:  call       void Base::get(int32)
  IL_0007:  nop
  IL_0008:  ret
} 
于 2014-06-26T10:26:32.823 回答