gpt4 book ai didi

c# - 如何使基类方法的属性应用于继承类?

转载 作者:行者123 更新时间:2023-11-30 18:41:25 28 4
gpt4 key购买 nike

注意:此问题已使用新信息更新。请参阅本文的下半部分。 (原始问题留在这里作为上下文。)


有什么方法可以定义我的属性,以便如果它是在被覆盖的方法上定义的,该属性仍然适用吗?

我问的原因是我有一个属性,它向方法中注入(inject)了一些行为,但是当调用该方法时,在子类中的任何情况下都不会应用该行为,我希望它是.

class BaseClass
{
[MyThing]
virtual void SomeMethod()
{
// Do something fancy because of the attribute.
}
}

class ChildClass
{
override void SomeMethod()
{
// Fancy stuff does happen here too...
base.SomeMethod();
}

void AnotherMethod()
{
// ...but not here. And I'd like it to =(
base.SomeMethod();
}
}

属性定义如下:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyThingAttribute : Attribute

当前使用该属性查找方法的代码如下:

var implementation = typeof(TheTypeWereCurrentlyInvestigating);
var allMethods = (from m in implementation.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
let attribs = (TransactionAttribute[]) m.GetCustomAttributes(typeof (TransactionAttribute), true)
where attribs.Length > 0
select Tuple.Create(m, attribs.Length > 0 ? attribs[0] : null)).ToList();

那部分不是我写的,我不能说我 100% 地完成了每一部分的工作......但我们现在可以假设我控制了所有涉及的代码。 (这是一个开源项目,所以我至少可以创建自己的版本,并向项目所有者提交补丁...)

我也有一些其他情况 - 基本上我想在我调用基类上的方法时注入(inject)这种行为,无论我以哪种方式到达那里 - 但如果我解决了这个问题,我可能会想到如何让其他人工作。如果没有,我会和他们一起回去。


更新:

好的,所以我坐下来处理 CaSTLe.Transactions 项目并创建了一些非常简单的测试来查看哪些有效,哪些无效。事实证明,我最初关于什么有效什么无效的假设有些不对。

我做了什么:
我创建了一个测试类,它有一个方法,用属性装饰,并调用 Assert验证行为是否被正确注入(inject)的方法(即存在交易)。然后我创建了几个继承这个测试类的类,看看在哪些情况下一切都按我预期的那样工作。

我发现了什么:
通过直接在测试类上调用测试方法以及从子类上的各种方法调用测试方法,我发现了以下有关有效和无效的信息:

Method called                 Access modifiers     Does it work?*************                 ****************     *************SomeMethod() on base class*   N/A                  YesOtherMethod() on child        neither              NO <-- headache!OtherMethod() on child        hiding (new)         NoSomeMethod() on child         hiding (new)         NoOtherMethod() on child        overrides            NoOtherMethod() on child*       overrides            YesSomeMethod() on child         overrides            Yes

除标有 * 的情况外,在所有情况下, base.SomeMethod()从测试中应用的方法调用。在第一种情况下,调用了相同的方法,但直接从测试中调用,因为不涉及子类。在第二种情况下(标记为 * 的情况),调用了覆盖方法,即 this.SomeMethod() ,所以这实际上等同于最后一种情况。我没有使用任何多余的限定符,所以在那个方法中调用只是 SomeMethod() .

我想要的:
我真正要解决的是标记为“头痛”的案例;如何将行为注入(inject)基类,即使我是从我的子类调用它。

我需要特定案例工作的原因是我在存储库中使用此模式,其中基类定义了一个 Save(T entity)Transaction 修饰的方法属性。目前,我必须重写此方法才能获得事务编排,这使得无法更改返回类型;在基类上它是 void ,但在我的实现中,我想将它设为 Error<T>反而。这在重写时是不可能的,并且由于我无法通过以不同方式命名方法来解决问题,所以我很茫然。

最佳答案

如果我是你,我会尝试改变你的设计。在 AnotherMethod() 中调用 base.SomeMethod() 当它在 AnotherMethod 的类中被覆盖时真的很臭。

你不能在 protected 方法中分解出 BaseClass.SomeMethod() 的相关部分,将你的属性放在这个新方法上并在 BaseClass.SomeMethod() 和 AnotherMethod() 中调用它,假设 ChildClass.SomeMethod()仍会调用它重写的方法吗?

关于c# - 如何使基类方法的属性应用于继承类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6847262/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com