C#中的Python风格类方法?

7 投票
5 回答
852 浏览
提问于 2025-04-15 17:59

有没有办法在C#中实现Python里的classmethod功能呢?

也就是说,想要一个静态函数,它可以根据调用它的子类,自动获取一个类型对象作为参数。

我想要的效果大概是这样的:

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.

(这里是同样的代码在codepad上的链接。)

5 个回答

2

根据不同的情况,你可能需要用到泛型或者虚方法。

3

我觉得你应该看看泛型这个概念。

这是微软的指南:

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

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) 也很简洁,而且更符合常规,那为什么还要这样写呢?可能没有必要。

撰写回答