简体   繁体   中英

C# abstract generic method call

With the abstract following class:

public abstract class A
{
    public static string MyMethod()
    {
        return "a";
    }
}

Why can't I built this derived abstract class:

public class B<T> where T : A
{
    public void AnotherMethod()
    {
        var S1 = base.MyMethod();    // not allowed
        var S2 = T.MyMethod();       // not allowed
    }
}

I don't understand why since MyMethod will be available in type T .

There are two misconceptions in your question that collectively prevent both your attempts from working.

First your B class is not in any way derived from the A class, you have only said that it takes a generic parameter that must inherit from A .

Second as the user @recursive pointed out, static methods do not participate in inheritance so MyMethod would only ever be available as A.MyMethod()

You can make at least your first attempt work if you remove the static modifier and make B inherit from A instead of using generics.

// Removed the static modifier
public abstract class A
{
    public string MyMethod()
    {
        return "a";
    }
}

// Made B inherit directly from A
public class B : A
{
    public void AnotherMethod()
    {
        var S1 = base.MyMethod(); //base technically isn't required
    }
}

Aside from the fact that A.MyMethod is static, which clearly will not work since anything static does not take part in inheritance, even if you made it not static it still will not work. For example, this will not work either:

public abstract class A {
   public string MyMethod() {
      return "a";
   }
}

public class B<T> where T : A {
   public void AnotherMethod() {
      var S1 = base.MyMethod();    // Line 1
      var S2 = T.MyMethod();       // Line 2
   }
}

Why?

You are saying where T : A which means that type T has to be a derived type from A . Your class B<T is not a derived type of A so Line 1 will not work.

But why is Line 2 not working?

T is a type and if T is inheriting A , then objects of type T will be able to do that. If you changed it like this, then it will work:

public abstract class A {
   public string MyMethod() {
      return "a";
   }
}

public class B<T> where T : A {
   public void AnotherMethod(T t) {
         t.MyMethod();
   }
}

public class C : A {

}

public class BClosed : B<C> {
   public void Foo(C c) {
      c.MyMethod();
      this.AnotherMethod(c);
   }
}

In the above code, C derives A which was your restriction. Then BClosed closes the generic type saying T is C so now you can call MyMethod of A and AnotherMethod of your generic.

Also, when you have a generic class you should use the generic type otherwise I do not see the use. So this is useless since it has no generic code:

public class B<T> where T : A {
   public void AnotherMethod() {

   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM