C #: dynamic polymorphism with non-polymorphic classes

I have a set of classes that I have not written, and they are read-only. Say, for example, that these classes are as follows:

public class Base { }
public class B : Base { }
public class C : B { }
public class D : Base { }

I want to add a method Foo()for all these classes, I use extension methods:

public static class Extensions {

  public static void Foo(this Base obj) {
      dynamic dynobj = obj;
      try {
        dynobj.Foo();
      }
      catch (RuntimeBinderException ex) {
          Console.WriteLine(ex.Message);
      }
  }

  public static void Foo(this B b) {
      Console.WriteLine("Foo in B");
  }

  public static void Foo(this C c) {
      Console.WriteLine("Foo in C");
  }

}

As you can see, I am trying to use the keyword dynamic, expecting it to find out the real type of my object and call its method Foo(). But ... dynobj.Foo()always fails.

static void Main(string[] args) {
    List<Base> list = new List<Base>();
    list.Add(new B());
    list.Add(new C());
    list.Add(new D());

    list.ForEach(x => x.Foo());
}

I know that I can use the adapter template, but I really have too many classes.

Is it a good idea to do this with dynamic? Can this work be done?

Thank.

+3
source share
3

- , Base 'Foo() , B, C D .

 public static void Foo(this Base obj) {
      try {
        Foo_(obj as dynamic);
      }
      catch (RuntimeBinderException ex) {
          Console.WriteLine(ex.Message);
      }
  }

  private static void Foo_(B b) {
      Console.WriteLine("Foo in B");
      b.ListOfBs.ForEach(x => x.Foo());
  }

  private static void Foo_(C c) {
      Console.WriteLine("C.Name = {0}", c.Name);
  }
+1

, Foo . - , . (). , .

, : Extensions.Foo(thing)

- (Dictionary), Foo.

- (), ?

public static class Extensions {

  private static Dictionary<Type, Action<Base>> callFoo = new Dictionary<Type, Action<Base>>
  {
    {typeof(B), b => (b as B).Foo()},
    {typeof(C), b => (b as C).Foo()}
  };

  public static void Foo(this Base obj) {
      try {
        callFoo[typeof(obj)](obj);
      }
      catch (RuntimeBinderException ex) {
          Console.WriteLine(ex.Message);
      }
  }

  public static void Foo(this B b) {
      Console.WriteLine("Foo in B");
  }

  public static void Foo(this C c) {
      Console.WriteLine("Foo in C");
  }

}
+5

, - Base , , - , , Foo().

Base Foo(), Foo() ( C Foo() B Foo())?

, -.

0

Source: https://habr.com/ru/post/1753699/


All Articles