什么是专业事件,领域,方法和属性?

时间:2018-04-13 08:06:17

标签: c# roslyn

我正在修改Roslyn,在this file我遇到了这段代码:

ISpecializedMethodReference specializedMethodReference = methodReference.AsSpecializedMethodReference;
if (specializedMethodReference != null)
{
    methodReference = specializedMethodReference.UnspecializedVersion;
}

在引用specializedMethodReference.UnspecializedVersion后,我会转到this file,此代码为:

/// <summary>
/// Represents the specialized event definition.
/// </summary>
internal interface ISpecializedEventDefinition : IEventDefinition
{
    /// <summary>
    /// The event that has been specialized to obtain this event. When the containing type is an instance of type which is itself a specialized member (i.e. it is a nested
    /// type of a generic type instance), then the unspecialized member refers to a member from the unspecialized containing type. (I.e. the unspecialized member always
    /// corresponds to a definition that is not obtained via specialization.)
    /// </summary>
    IEventDefinition/*!*/ UnspecializedVersion
    {
        get;
    }
}

/// <summary>
/// Represents reference specialized field.
/// </summary>
internal interface ISpecializedFieldReference : IFieldReference
{
    /// <summary>
    /// A reference to the field definition that has been specialized to obtain the field definition referred to by this field reference. 
    /// When the containing type of the referenced specialized field definition is itself a specialized nested type of a generic type instance, 
    /// then the unspecialized field reference refers to the corresponding field definition from the unspecialized containing type definition.
    /// (I.e. the unspecialized field reference always refers to a field definition that is not obtained via specialization.)
    /// </summary>
    IFieldReference UnspecializedVersion { get; }
}

/// <summary>
/// Represents reference specialized method.
/// </summary>
internal interface ISpecializedMethodReference : IMethodReference
{
    /// <summary>
    /// A reference to the method definition that has been specialized to obtain the method definition referred to by this method reference. 
    /// When the containing type of the referenced specialized method definition is itself a specialized nested type of a generic type instance, 
    /// then the unspecialized method reference refers to the corresponding method definition from the unspecialized containing type definition.
    /// (I.e. the unspecialized method reference always refers to a method definition that is not obtained via specialization.)
    /// </summary>
    IMethodReference UnspecializedVersion { get; }
}

/// <summary>
/// Represents the specialized property definition.
/// </summary>
internal interface ISpecializedPropertyDefinition : IPropertyDefinition
{
    /// <summary>
    /// The property that has been specialized to obtain this property. When the containing type is an instance of type which is itself a specialized member (i.e. it is a nested
    /// type of a generic type instance), then the unspecialized member refers to a member from the unspecialized containing type. (I.e. the unspecialized member always
    /// corresponds to a definition that is not obtained via specialization.)
    /// </summary>
    IPropertyDefinition/*!*/ UnspecializedVersion
    {
        get;
    }
}

我已经三次阅读这些评论了,我已经做了一些谷歌搜索,我不知道他们在谈论什么。有人可以请我提供一些解释,最好有一些例子吗?

编辑:

感谢@DaisyShipton的回答以及@HansPassant的评论,我现在认为我对它的全部内容有一个模糊的概念。 Roslyn在可能的情况下优化通用字段和方法的使用(称之为专用),但随后要与C#元数据标准兼容,它必须发出未经优化的元数据(称之为 unspecialized )。

为了测试@ DaisyShipton的答案,我将答案中的Foo<T>Bar类复制到我用作测试程序的C#程序中。然后我修改了this bit of Roslyn

internal BlobHandle GetFieldSignatureIndex(IFieldReference fieldReference)
{
    BlobHandle result;
    ISpecializedFieldReference specializedFieldReference = fieldReference.AsSpecializedFieldReference;
    if (specializedFieldReference != null)
    {
        fieldReference = specializedFieldReference.UnspecializedVersion;
    }

如下:

internal BlobHandle GetFieldSignatureIndex(IFieldReference fieldReference)
{
    BlobHandle result;
    ISpecializedFieldReference specializedFieldReference = fieldReference.AsSpecializedFieldReference;

   // Added code
   if (fieldReference.Name == "field")
   {
      if (specializedFieldReference == null)
         Console.WriteLine(fieldReference.ToString() + "   Not considered specialized.");
      else
      {
         Console.WriteLine(fieldReference.ToString() + 
                           "   Is considered specialized, converted to: " +
                           specializedFieldReference.UnspecializedVersion.ToString());
      }
   }

    if (specializedFieldReference != null)
    {
        fieldReference = specializedFieldReference.UnspecializedVersion;
    }

结果如下:

Console window screen shot

我不明白为什么这段代码被多次击中(9)。可以看出,对于将字段引用视为专用的8个案例,要么因为int是已知结果,要么已知T的类型为{{ 1}}。但我无法将9个命中与测试程序中的特定位源代码相关联。

1 个答案:

答案 0 :(得分:3)

相信它与泛型有关,以及你是否正在处理&#34; general&#34;中的成员声明。泛型类型,或已有类型参数的类型。 (A&#34;封闭,构造类型&#34;在C#语言规范术语中,虽然我总是发现泛型术语很棘手。)

根据typeof运算符,我的意思是一个例子:

public void Foo<T>()
{
    // We always know what this will be: we're specifying a closed constructed type
    Console.WriteLine(typeof(List<int>));

    // At compile-time, this isn't a closed, constructed type, because
    // it uses a type parameter as the type argument. At execution time,
    // it will take on a closed, constructed type based on the actual type
    // of T for this call.
    Console.WriteLine(typeof(List<T>));

    // This is a generic type definition, with no type argument
    Console.WriteLine(typeof(List<>));
}

现在,要查看Roslyn中的等效内容,请查看相关参考资料:

public class Foo<T>
{
    public int field;

    public void Method() 
    {
        // I expect this to be an unspecialized reference
        int x = field;
    }
}

public class Bar
{
    public void Method() 
    {
        Foo<string> foo = new Foo<string>();
        // I expect this to be a specialized field reference
        int x = foo.field;
    }
}

泛型类型中的方法,事件等会发生同样的事情。使用泛型方法会变得更加复杂,潜在地,方法本身可以引入另一个类型参数......