【问题标题】:How does this work - .NET wizardry (undocumented features?)这是如何工作的 - .NET 魔法(未记录的功能?)
【发布时间】:2013-04-21 20:23:20
【问题描述】:

找到this code

这里是gyst:

视图模型:

[ExtendWith(typeof(ValidationTemplate))]
public class PersonViewModel :INotifyPropertyChanged
{
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {

            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

ExtendWithAttribute

public class ExtendWithAttribute : Attribute
{
    public ExtendWithAttribute(Type type)
    {
    }
}

验证模板

public class ValidationTemplate : IDataErrorInfo
{
    private INotifyPropertyChanged target;

    public object Target
    {
        get
        {
            return target;
        }
        set
        {
            target = (INotifyPropertyChanged)value;
            validator = ValidationFactory.GetValidator(target.GetType());
            validationResult = validator.Validate(Target);
            target.PropertyChanged += Validate;
        }
    }

    private void Validate(object sender, PropertyChangedEventArgs e)
    {
        if (validator != null)
        {
            validationResult = validator.Validate(target);
        }
    }

    private IValidator validator;
    private ValidationResult validationResult;

    public string Error
    {
        get
        {
            return string.Join(Environment.NewLine, validationResult.Errors.Select(x => x.ErrorMessage).ToArray());
        }
    }

    public string this[string propertyName]
    {
        get
        {
            return string.Join(Environment.NewLine, validationResult.Errors.Where(x => x.PropertyName == propertyName).Select(x => x.ErrorMessage).ToArray());
        }
    }
}

如果我们创建一个 PersonViewModel 实例,我们会得到:

  1. ValidationTemplate 已实例化 - 我 假设 因为我们将类型传递到此 ExtendWith 属性中,.NET 会自动实例化该类型,但我无法在任何地方找到任何确认此行为的信息 p>

  2. ValidationTemplate 目标属性被“神奇地”调用,它接收到对 PersonViewModel 的引用。哪个 .NET 行为片段调用了这个?我找不到任何描述此行为的文档 - 似乎它依赖于命名约定?还有其他可以填充的属性吗?这是什么魔法:)

  3. 1234563然而它可以工作,不知何故它能够从某个地方使用这个 ValidationTemplate 任意对象。

更新:所以在我在调试器中检查了 PersonViewModel 之后,得到了以下有趣的答案:

var viewModel = new PersonViewModel();
var isDataErrorInfo = viewModel is IDataErrorInfo; // true
var isDataErrorInfo = viewModel is ValidationTemplate; // false

代码基于 Caliburn.Micro,bootstrapper 是 vanilla,其中没有任何内容。我手动实例化了 PersonViewModel 以确认调用扩展程序类的不是 WPF 特定行为,并且我确实在 Target 属性触发时获得了 setter/getter。

谁能解释所有这些奇怪的行为。我感觉这是 .NET 框架的一些内部/未记录的功能/黑客。

【问题讨论】:

    标签: .net attributes custom-attributes


    【解决方案1】:

    该项目依赖于Hereder。花了我一整天的时间到处寻找,直到我检查 csproj 并看到构建后的任务。现在说得通了。

    【讨论】:

      【解决方案2】:

      这里没有魔法。属性是 .NET 中一个有据可查的特性。属性本质上是关于可以添加的类的一些额外信息,可以通过反射访问。你可以阅读更多关于它的信息here

      编写良好的 MVVM 代码通常看起来很像“魔术”。实际上,通常有一个编写良好的框架,它使用反射和其他技巧来自动连接它。很可能很多实际工作都在 Caliburn.Micro.dll 或 FluentValidation.dll 中。这样你就可以一次编写引导逻辑,然后在你的所有 WPF/Silverlight/等上重用它。项目。除非你也有这些代码,否则你可以使用类似 here 建议的反射器工具来查看它们,或者只是与 GitHub 存储库的所有者交谈,看看你是否也可以访问它们。

      【讨论】:

      • attribute 的文档是我广泛阅读并知道它是如何工作的。在这一点上,我确信这是 .NET 框架的一个内部特性,而不是 caliburn/fluent 的任何东西,因为我已经通过将案例简化为一个新项目来消除这些变量。这是不同的,属性参数中指定的类型的激活是由 .net 框架在内部完成的,并且它与主类“混合”,即 PersonViewModel 正在由 ValidationTemplate 中的代码扩展。我正在寻找记录这种行为的材料
      猜你喜欢
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      相关资源
      最近更新 更多