|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.CodeDom;
namespace System.ComponentModel.Design.Serialization;
/// <summary>
/// An expression context is an object that is placed on the context stack and contains the most
/// relevant expression during serialization. For example, take the following statement:
/// button1.Text = "Hello";
/// During serialization several serializers will be responsible for creating this single statement.
/// One of those serializers will be responsible for writing "Hello".
/// There are times when that serializer may need to know the context in which it is creating its expression.
/// In the above example, this isn't needed, but take this slightly modified example:
/// button1.Text = rm.GetString("button1_Text");
/// Here, the serializer responsible for writing the resource expression needs to know the names of the target objects.
/// The ExpressionContext class can be used for this. As each serializer creates an expression and
/// invokes a serializer to handle a smaller part of the statement as a whole,
/// the serializer pushes an expression context on the context stack.
/// Each expression context has a parent property that locates the next expression context on the stack,
/// which provides a way for easy traversal.
/// </summary>
public sealed class ExpressionContext
{
public ExpressionContext(CodeExpression expression, Type expressionType, object owner, object? presetValue)
{
Expression = expression.OrThrowIfNull();
ExpressionType = expressionType.OrThrowIfNull();
Owner = owner.OrThrowIfNull();
PresetValue = presetValue;
}
public ExpressionContext(CodeExpression expression, Type expressionType, object owner) : this(expression, expressionType, owner, null)
{
}
/// <summary>
/// The expression this context represents.
/// </summary>
public CodeExpression Expression { get; }
/// <summary>
/// The type of the expression. This can be used to determine if a
/// cast is needed when assigning to the expression.
/// </summary>
public Type ExpressionType { get; }
/// <summary>
/// The object owning this expression. For example, if the expression
/// was a property reference to button1's Text property, Owner would
/// return button1.
/// </summary>
public object Owner { get; }
/// <summary>
/// Contains the preset value of an expression, should one exist.
/// For example, if the expression is a property reference expression
/// referring to the Controls property of a button, PresetValue will
/// contain the instance of Controls property because the property is
/// read-only and preset by the object to contain a value. On the other
/// hand, a property such as Text or Visible does not have a preset
/// value and therefore the PresetValue property will return null.
/// Serializers can use this information to guide serialization.
/// For example, take the following two snippets of code:
/// Padding p = new Padding();
/// p.Left = 5;
/// button1.Padding = p;
/// button1.Padding.Left = 5;
/// The serializer of the Padding class needs to know if it should
/// generate the first or second form. The first form would be
/// generated by default. The second form will only be generated
/// if there is an ExpressionContext on the stack that contains a
/// PresetValue equal to the value of the Padding object currently
/// being serialized.
/// </summary>
public object? PresetValue { get; }
}
|