English 中文(简体)
是否有办法在C#中采用像花on这样的分类方法?
原标题:Is there a way to make classmethods in C# like python?

In python, an instance method self points to the class instance, just like this in C#. In python, a class method self points to the class. Is there a C# equivalent?

这一点是有益的,例如:

例子:

class A:
  values = [1,2]

  @classmethod
  def Foo(self):
    print "Foo called in class: ", self, self.values

  @staticmethod
  def Bar():
    print "Same for all classes - there is no self"

class B(A):
  # other code specific to class B
  values = [1,2,3]
  pass

class C(A):
  # other code specific to class C
  values = [1,2,3,4,5]
  pass

A.Foo()
A.Bar()
B.Foo()
B.Bar()
C.Foo()
C.Bar()

成果:

Foo called in class:  __main__.A [1, 2]
Same for all classes - there is no self
Foo called in class:  __main__.B [1, 2, 3]
Same for all classes - there is no self
Foo called in class:  __main__.C [1, 2, 3, 4, 5]
Same for all classes - there is no self

这可以成为一种伟大的工具,使在班级情况下(无一例)的普通法典能够提供由子级界定的定制行为(无需次等)。

在我看来,C#静态方法正好像是伪装方法,因为没有哪类人实际使用这种方法。

But is there a way to do class methods in C#?? Or at least determine which class invoked a method, for example:

public class A
{
  public static List<int> values;

  public static Foo()
  {
    Console.WriteLine("How can I figure out which class called this method?");
  }
}

public class B : A
{
}

public class C : A
{
}

public class Program
{
  public static void Main()
  {
    A.Foo();
    B.Foo();
    C.Foo();
  }
}
最佳回答

There is no way to do this using regular static methods. Possible alternatives include:

(1) 虚拟、压倒性的方法:

public class A
{
    public virtual void Foo()
    {
        Console.WriteLine("Called from A");
    }
}

public class B : A
{
    public override void Foo()
    {
        Console.WriteLine("Called from B");
    }
}

2) 推广方法:

public class A
{
}

public class B : A
{
}

public static class Extensions
{
    /// Allows you to do:
    /// var whoop = new B();
    /// whoop.Foo();
    public static void Foo<T>(this T thing) where T : A
    {
        Console.WriteLine("Called from " + thing.GetType().Name);
    }
}

3) 假定A和B有违约构造:

public static class Cached<T> where T : class, new()
{
    private static T _cachedInstance;

    public static T Instance
    {
        get { return _cachedInstance ?? (_cachedInstance = new T()); }
    }
}

public static class Extensions
{
    public static void Example()
    {
        Cached<B>.Instance.Foo();
    }

    public static void Foo<T>(this T thing) where T : A, new()
    {
        Console.WriteLine("Called from " + typeof(T).Name);
    }
}
问题回答

无。 每一种电话方法都必须把自己和<代码>><>ts/code>的可变性推向某些静态可用打或字体。

可通过<http://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.questcontext.aspx” rel=“nofollow”>CallContext储存电话线。 我曾经利用这种机制储存关于功能电话链的偏重信息。

您可使用AOP框架,如Postsharp处理CallContext。 这是我所做的事。 我为此目的使用了这个词。 我正在把铁P带入我的手里,希望能找到C#的物体和向铁蓬发出呼吁的方法。 它运作良好。 不幸的是,我再也没有这样的法典。

此处为C#的相应代码:

public class A {

  protected int[] values;

  public A () {
    values = new int[] { 1, 2 };
  }

  public void Foo() {
    Console.WriteLine("Foo called in class: {0}, values = {1}", this.GetType().Name, String.Join(",", values));
  }

  public static void Bar() {
    Console.WriteLine("Same for all classes.");
  }

}

public class B : A {

  public B () {
    values = new int[] { 1, 2, 3 };
  }

}

public class C : A {

  public C () {
    values = new int[] { 1, 2, 3, 4, 5 };
  }

}

• 要求检查方法,以证明:

new A().Foo();
A.Bar();
new B().Foo();
B.Bar();
new C().Foo();
C.Bar();

产出:

Foo called in class: A, values = 1,2
Same for all classes.
Foo called in class: B, values = 1,2,3
Same for all classes.
Foo called in class: C, values = 1,2,3,4,5
Same for all classes.

<C.Bar()等于A.Bar(,该方法将不了解差异。 这种方法载于<代码>A类别,但汇编者也请其使用衍生类别。

You could use generics to do this

public class _A<T> where T : _A<T> {

  public static int[] Values=new int[] {1,2};

  public static void Foo() {
    Console.WriteLine(String.Format("Foo called in class: {0} {1}",typeof(T).Name, String.Join(",",T.Values)));
  }
}

public class A : _A<A> {
}

public class B : _A<B> {
  public static new int[] Values=new int[] {1,2,3};
}

public class C : _A<C> {
  public static new int[] Values=new int[] {1,2,3,4,5};
}

困难在于,你们需要知道使用A的类型变量,这样你就能够做A.Foo(),但你可以做B.Foo()和C.Foo()。 但是,你可以到A.Foo(......)并去。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签