无论这是否是一个好主意,是否可以实现一个接口,其中执行函数知道调用对象的类型?
class A { private C; public int doC(int input) { return C.DoSomething(input); } } class B { private C; public int doC(int input) { return C.DoSomething(input); } } class C { public int DoSomething(int input) { if(GetType(CallingObject) == A) { return input + 1; } else if(GetType(CallingObject) == B) { return input + 2; } else { return input + 3; } } }
在我看来,这是一个糟糕的编码实践(因为参数不会改变,但输出会)但除此之外是否可能?
我在某种情况下,我想要一些特定的类型能够调用某个函数,但我无法排除对该函数的访问.我想过有一个"类型"参数
DoSomething(int input, Type callingobject)
但是不能保证调用对象会使用GetType(this),而不是GetType(B)来欺骗B而不管它们自己的类型.
这会像检查callstack一样简单(相对简单)吗?
编辑
请把JaredPar的答案(如果你想的话)和John Feminella的答案一起投票.我无法将这两个答案都标记为已被接受,我接受了John Feminella的答案,因为它特别符合我的要求,而Jared的答案则提出了我之前未曾考虑过的解决方案.
首先,是的,这样做是一个可怕的想法,并打破了各种坚实的设计原则.你应该考虑另一种方法,如果它是开放的,就像简单地使用多态 - 这似乎可以重构为一个非常明确的单一调度的情况.
其次,是的,这是可能的.使用System.Diagnostics.StackTrace
走栈; 然后得到适当的StackFrame
一级.然后确定该方法是通过使用呼叫者GetMethod()
对StackFrame
.请注意,构建堆栈跟踪是一项可能很昂贵的操作,并且您的方法的调用者可能会模糊事物的真正来源.
编辑:来自OP的这个评论非常清楚,这可能是一个通用或多态的方法.@devinb,你可能想考虑提出一个新问题,提供你正在尝试做的更多细节,我们可以看看它是否适合一个好的解决方案.
简短的版本是我最终会有30或40个完全相同的功能,只需要一两行. - devinb(12秒前)
作为一种替代方法,您是否考虑过根据要求该类的对象类型提供不同的类.说以下
public interface IC { int DoSomething(); } public static CFactory { public IC GetC(Type requestingType) { if ( requestingType == typeof(BadType1) ) { return new CForBadType1(); } else if ( requestingType == typeof(OtherType) { return new CForOtherType(); } ... } }
这将是一种更清晰的方法,而不是每种方法基于调用对象改变它的行为.它将干净地分离出对IC的不同实现的关注.此外,他们都可以代理回到真正的C实现.
编辑检查callstack
正如其他几个人所指出的,你可以检查callstack以确定哪个对象立即调用该函数.但是,这不是一种简单的方法来确定您想要特殊情况的对象之一是否正在呼叫您.例如,我可以执行以下操作来从SomeBadObject中调用您,但是您很难确定我是这样做的.
public class SomeBadObject { public void CallCIndirectly(C obj) { var ret = Helper.CallDoSomething(c); } } public static class Helper { public int CallDoSomething(C obj) { return obj.DoSomething(); } }
你当然可以走回调用堆栈.但是这更加脆弱,因为当另一个对象调用DoSomething时,SomeBadObject可能是一个完全合法的路径.