Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove redundant C# code without using interface

Tags:

c#

wcf

Please consider two restrictions -

  1. Can't move MyProperty to interface or abstract class.
  2. FooEventHandler is a dotnet framework method hence can't change paramter type.

I have MyProperty defined in several classes.

class A
    {
        public string MyProperty { get; set; }
    }
    class B
    {
        public string MyProperty { get; set; }
    }
    class C
    {
        public string MyProperty { get; set; }
    }

Method FooEventHandler updates this property for all parameters it receives.

public object FooEventHandler(object obj)
    {
        object toReturn = null;
        if (obj.GetType() == typeof(A))
        {
            (obj as A).MyProperty = "updated";
            toReturn = obj;
        }
        else if (obj.GetType() == typeof(B))
        {
            (obj as B).MyProperty = "updated";
            toReturn = obj;
        }
        else if (obj.GetType() == typeof(C))
        {
            (obj as C).MyProperty = "updated";
            toReturn = obj;
        }
        return toReturn;
    }

And FooEventHandler is called repeatedly like this -

static void Main(string[] args)
    {
        Program program = new Program();
        A objA = new A();
        program.FooEventHandler(objA);
        B objB = new B();
        program.FooEventHandler(objB);
        C objC = new C();
        program.FooEventHandler(objC);
    }

Please suggest a way to remove redundant code in Foo, considering above two restrictions in general.

To be more precise, I have encountered this issue while using ParameterInspector in WCF. I am trying to modify propery of all the requests intercepted here and had to write Switch Case based on operationName.

A, B, C, D classes as said above are proxies. So don't want to modify them at first place. Since updating service Reference will overwrite my iterface changes.

public object BeforeCall(string operationName, object[] inputs){
    // update inputs[0] properties
    }

Thank you for your help.

like image 883
Abhijeet Avatar asked Nov 30 '22 02:11

Abhijeet


1 Answers

You can actually have your classes implement an interface, to make this easier to work with. The key is that the generated service reference classes are partial, meaning you can do this in a separate file, which won't be overwritten when the code is regenerated:

namespace ServiceReferenceNamespace {
 public partial class A : IMyProperty { }
 public partial class B : IMyProperty { }
 public partial class C : IMyProperty { }
}

Where IMyProperty is:

public interface IMyProperty { string MyProperty { get; set; } }

Then you can change your FooEventHandler method to take an IMyProperty, or take an object and check obj is IMyProperty (or use as, so the check is only done once). This lets you use the property simply, without any reflection or dynamic complexities and the runtime performance impacts of those approaches.

like image 90
Tim S. Avatar answered Dec 09 '22 10:12

Tim S.