How to reorganize overloaded methods

I have methods:

public MyReturnType MyMethod(Class1 arg)
{
 //implementation
}

public MyReturnType MyMethod(Class2 arg)
{
 //implementation
}

//...

public MyReturnType MyMethod(ClassN arg)
{
 //implementation
}

decimal, string, DateTime in [Class1, ..., ClassN]
and one common method:

public MyReturnType MyMethod(object obj)
{
 if(obj == null)
  throw new ArgumentNullException("obj");
 if(obj is MyClass1)
  return MyMethod((Class1)obj);
 if(obj is MyClass2)
  return MyMethod((Class2)obj);
 //...
 if(obj is MyClassN)
  return MyMethod((ClassN)obj);
 return MyMethod(obj.ToString()); //MyMethod(string) implemented.
}

How can I reorganize this code? I can use attributes and a component model, something like this:

public class MyAttribute : Attribute
{
 public Type Type { get; set; }
}

public MyReturnType MyMethod(object obj)
{
    if(obj == null)
        throw new ArgumentNullException("obj");
 var protperty = TypeDescriptor.GetProperties(this, new Attribute[] { new MyAttribute() })
  .Cast<PropertyDescriptor>().FirstOrDefault(x =>
   x.GetAttribute<MyAttribute>().Type.IsInstanceOfType(obj));
 if (protperty != null)
  return protperty.GetValue(obj) as MyReturnType;
 return MyMethod(obj.ToString());
}

but it is rather difficult to understand and may create some errors. For example, if someone declares a method like

[MyAttribute(Type = ClassNplus1)]
public NotMyReturnType MyMethod(ClassNplus1 arg);

Any other ideas for creating an extensible system where adding a new class is only required to add one method? (add code in one place)

+3
source share
3 answers

, :

public MyReturnType MyMethod<T>(T arg)
{
    // implementation
}

, T :

public MyReturnType MyMethod<T>(T arg) where T : MyClassBase
{
    // implementation
}

T , MyClassBase, , ( ) MyClassBase. .

:

MyMethod(new MyClass1());
MyMethod(new MyClass2());
MyMethod(new MyClass3());

, , , T, , :

MyMethod<MyClass1>(new MyClass1());
MyMethod<MyClass2>(new MyClass2());
MyMethod<MyClass3>(new MyClass3());
+4

You can use Generics and Attributes to describe some metadata about the class. Generators are likely to clear your if statements.

Hmmm ...

public class MyClass<T>
{
   public OtherClass ReturnSomething(T checkThisType)
   {
   }
}

Sorry, I could be more visual. Hope this helps.

0
source

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


All Articles