如何使用 ReSharper SDK 创建 [CustomAttribute(typeof(GenericType<,>))]?

Posted

技术标签:

【中文标题】如何使用 ReSharper SDK 创建 [CustomAttribute(typeof(GenericType<,>))]?【英文标题】:How to create [CustomAttribute(typeof(GenericType<,>))] with ReSharper SDK? 【发布时间】:2012-01-16 09:00:52 【问题描述】:

有没有办法使用泛型类型的typeof 表达式创建属性?

以下代码仅部分起作用:

CSharpElementFactory factory = ...
IClassDeclaration typeDeclaration = ...

IClassDeclaration classDeclaration = ...
IType[] attributeTypeParameters = 
    (from typeParameter in classDeclaration.TypeParameters
    select (IType)TypeFactory.CreateUnknownType(module)).ToArray();
IType classType = TypeFactory.CreateType(classDeclaration.DeclaredElement, 
                                         attributeTypeParameters);

var attribute = factory.CreateAttribute(
    new SpecialAttributeInstance(
        ClrTypeNames.ContractClassAttribute,
        module,
        () => new[]  new AttributeValue(classType) ,
        Enumerable.Empty<Pair<string, AttributeValue>>));
typeDeclaration.AddAttributeAfter(attribute, null);

【问题讨论】:

【参考方案1】:

我怀疑问题在于您定义类声明的方式。这是一个代码 sn-p,它在上下文中使用[ContractClass(typeof(Dictionary&lt;,&gt;))] 装饰类

ClrTypeName contractClassAttribute = 
  new ClrTypeName("System.Diagnostics.Contracts.ContractClassAttribute");
ClrTypeName someGenericClass = new ClrTypeName("System.Collections.Generic.Dictionary`2");

var module = provider.PsiModule;
var owner = provider.GetSelectedElement<IClassDeclaration>(true, true);
var factory = CSharpElementFactory.GetInstance(module);

var someGenericTypeElement = TypeElementUtil.GetTypeElementByClrName(someGenericClass, module);
var unknownType = TypeFactory.CreateUnknownType(module);
var someGenericType = TypeFactory.CreateType(someGenericTypeElement, unknownType, unknownType);
var contractClassTypeElement = TypeElementUtil.GetTypeElementByClrName(contractClassAttribute, module);
var attribute = factory.CreateAttribute(contractClassTypeElement, new[] new AttributeValue(someGenericType),
                                        EmptyArray<Pair<string, AttributeValue>>.Instance);
owner.AddAttributeAfter(attribute, null);

【讨论】:

TypeElementUtil.GetTypeElementByClrName(someGenericClass, module) 为空。所以TypeFactory.CreateType(someGenericTypeElement... 抛出异常。 您使用的是什么版本的 .Net? (我的意思是,项目的 .Net 框架目标。) 您的 sn-p 有效,因为您使用的是 existing 类型,但在我的情况下,我正在创建一个全新的泛型类,应该由 typeof(GenericType&lt;,&gt;) 引用在一个属性中。 好的,那么假设你有一个现有的类型。在这种情况下,您只需接受它的声明:var someGenericType = TypeFactory.CreateType(someDeclarationIHave.DeclaredElement, ...)

以上是关于如何使用 ReSharper SDK 创建 [CustomAttribute(typeof(GenericType<,>))]?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Resharper SDK 从 IClrDeclaredElement 获取 IDeclaredType

如何使用 ReSharper SDK 确定方法的返回类型?

如何从 IType (Resharper 8 SDK) 获取 Type 实例

使用 Resharper SDK 查找 ITypeElement 或 IDeclaredElement 的用法

上下文操作的 ReSharper SDK 测试不起作用

无法调试使用 SDK 制作的 ReSharper 插件