2

考虑这种方法和描述:

[Description("It must be called from a property, else it is a runtime error.")]
protected T Load<T>()
{
   return InternalLoad<T>();
}

该方法的设计要求调用者必须是属性,否则InternalLoad会抛出异常。它使用StackFrame来获取调用者名称,如果不是get_<PropertyName>or的形式set_<PropertyName>,则抛出异常。这一切都发生在我不喜欢的运行时。

我想知道是否有任何方法可以确保在编译时调用者始终是一个属性。换句话说,应该只允许属性调用此方法。有什么方法可以在编译时检查吗?

作为最后的手段,是否可以扩展将使用自定义属性(例如CallableFromAttribute)来确保这一点的 C# 编译器?

我想让它尽可能灵活:

[CallableFrom(Caller.Property)] //Caller is an enum
protected T Load<T>()
{
   return InternalLoad<T>();
}

[CallableFrom(Caller.Property | Caller.Method)]
protected T SomeOtherLoad<T>()
{
  //code
}

接着

public string Method()
{
    var x = this.SomeOtherLoad<string>(); //okay
    var y = this.Load<string>();          //compilation error !!
}

让我知道是否有任何混淆。我会澄清的。:-)


我需要此功能,因为我正在尝试实现一个名为的类,该类PropertyManager用作其他需要定义属性的类的基类。这个类的典型用法是这样的:

public sealed Vendor : PropertyManager
{
    public string VendorName
    {
       get { return this.Load<string>(); }
       set { this.Store(value); }
    }
    public DateTime Created
    {
       get { return this.Load<DateTime>(); }
       set { this.Store(value); }
    }
}

在基类中定义的方法和方法发现调用Load它们的属性的名称;将该名称视为key,它从字典中读取关联的值(在 的情况下),或写入它(在 的情况下)。它引发属性更改和更改事件。它还支持撤消,因为可以轻松跟踪对属性所做的所有更改。StoreLoadStoreProperyMananger

4

1 回答 1

0

No, there is no such possibility at compile time. There cannot be: all such compile-time checks are based on whether a method is accessible from the method that accesses it, not the method that calls it. If a property setter exposes Load via a delegate, there is no possible way even in a theoretical modified compiler to check at compile time that nobody uses that delegate other than another property setter.

I'm not sure why you want this, so I'm assuming that your check is necessary and your runtime check verifies exactly what you need it to. If that assumption is wrong, there may be some options, but your question as asked is simply impossible.

于 2013-01-14T11:51:56.403 回答