我正在修改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;
}
结果如下:
我不明白为什么这段代码被多次击中(9)。可以看出,对于将字段引用视为专用的8个案例,要么因为int
是已知结果,要么已知T
的类型为{{ 1}}。但我无法将9个命中与测试程序中的特定位源代码相关联。
答案 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;
}
}
泛型类型中的方法,事件等会发生同样的事情。使用泛型方法会变得更加复杂,潜在地,方法本身可以引入另一个类型参数......