不使用接口删除冗余的C#代码

Abh*_*eet 4 c# wcf

请考虑两个限制 -

  1. 无法将MyProperty移动到接口或抽象类.
  2. FooEventHandler是一个dotnet框架方法,因此无法更改参数类型.

我在几个类中定义了MyProperty.

class A
    {
        public string MyProperty { get; set; }
    }
    class B
    {
        public string MyProperty { get; set; }
    }
    class C
    {
        public string MyProperty { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

方法FooEventHandler为其接收的所有参数更新此属性.

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;
    }
Run Code Online (Sandbox Code Playgroud)

和FooEventHandler一样被反复调用 -

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);
    }
Run Code Online (Sandbox Code Playgroud)

请提出一种方法来删除Foo中的冗余代码,一般考虑上述两个限制.

更准确地说,我在WCF中使用ParameterInspector时遇到了这个问题.我试图修改这里截获的所有请求的属性,并且必须根据operationName编写Switch Case.

如上所述的A,B,C,D类是代理.所以不想在第一时间修改它们.由于更新服务引用将覆盖我的iterface更改.

public object BeforeCall(string operationName, object[] inputs){
    // update inputs[0] properties
    }
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助.

Tim*_* S. 10

实际上,您可以让您的类实现一个接口,以便更轻松地使用它.关键是生成的服务引用类是partial,这意味着您可以在单独的文件中执行此操作,在重新生成代码时不会覆盖该文件:

namespace ServiceReferenceNamespace {
 public partial class A : IMyProperty { }
 public partial class B : IMyProperty { }
 public partial class C : IMyProperty { }
}
Run Code Online (Sandbox Code Playgroud)

在哪里IMyProperty:

public interface IMyProperty { string MyProperty { get; set; } }
Run Code Online (Sandbox Code Playgroud)

然后你可以改变你的FooEventHandler方法来采取IMyProperty,或采取object和检查obj is IMyProperty(或使用as,所以检查只进行一次).这使您可以简单地使用该属性,而不会出现任何反射或动态复杂性以及这些方法对运行时性能的影响.


Aus*_*nen 5

假设dynamic可以使用:

dynamic toReturn = obj;
toReturn.MyProperty = "updated";
return toReturn;
Run Code Online (Sandbox Code Playgroud)

如果MyProperty不存在,这将抛出obj.

测试:

[Test]
public void X()
{
    A objA = new A();
    var x = FooEventHandler(objA);
    Assert.IsInstanceOf<A>(x);
    Assert.AreEqual("updated", (x as A).MyProperty);

    B objB = new B();
    var y = FooEventHandler(objB);
    Assert.IsInstanceOf<B>(y);
    Assert.AreEqual("updated", (y as B).MyProperty);

    C objC = new C();
    var z = FooEventHandler(objC);
    Assert.IsInstanceOf<C>(z);
    Assert.AreEqual("updated", (z as C).MyProperty);

    D objD = new D();
    Assert.Throws<RuntimeBinderException>(() => FooEventHandler(objD));
}

class D {}
Run Code Online (Sandbox Code Playgroud)