什么是来自java的类<annotation>的c#等价物?</annotation>

时间:2014-10-12 07:51:12

标签: c#

编辑:提出问题的另一种方式:

  • 如果Java中的“ Class&lt; Object&gt; ”等同于C#中的“ Type
  • 等同于“ Class&lt; Annotation&gt; ”的内容是什么?

下面的代码来自我正在编写的Unity3D资产,所以c#的版本很老:“大多数但不完全是4.0”,谷歌告诉我。

下面的代码有效(模块化不可避免的错误),我的问题在于类型签名的表现力。问题在于VisitAnnotatedFields()方法的签名,特别是attrType参数 - 它总是由某些子类型的属性所支持。

在Java中,我将Java中的等效参数定义为“Class&lt; Annotation&gt;”为了告诉编译器调用者必须传递Annotation的子类型。

问题不是具体的注释,我以前在其他情况下遇到过这个问题;我只是在必要时通过检查和铸造来解决它。

有没有办法在C#中表达这个,或者我的所有类型引用都必须是“Type”,我需要编写一堆文档和代码来检查是否传递了正确的内容?

示例代码:

[AttributeUsage(AttributeTargets.Field)]
public class NotNullAttribute : Attribute {
}

class NullReferenceCheck : SceneGameObjectCheck {
  public override IEnumerable<CheckFailure> Check(MonoBehaviour target){
    var failures = new List<CheckFailure>();
    ReflectionUtils.VisitAnnotatedFields(
      target,
      typeof(NotNullAttribute),
      (FieldInfo field, Attribute attr) => {
        // do the check for null value and add to failures
      });

    return failures;
  }
}

public static void VisitAnnotatedFields(
  MonoBehaviour target,
  Type attrType,
  Action<FieldInfo, Attribute> closure)
{
  IEnumerable<FieldInfo> fieldInfos = target.GetAllFields();
  foreach( var iField in fieldInfos ){
    object[] customAttributes = iField.GetCustomAttributes(false);
    foreach( var jAttr in customAttributes ){
      if( jAttr.GetType().IsAssignableFrom(attrType) ){
        closure.Invoke(iField, (Attribute) jAttr);
      }
    }
  }
}

2 个答案:

答案 0 :(得分:4)

虽然一般答案是否定的 - 但Type没有编译类型检查 - 我相信你仍然可以使用泛型来达到你的目的,就像这样:

public static void VisitAnnotatedFields<TAttribute>(
  MonoBehaviour target,
  Action<FieldInfo, TAttribute> closure)
  where TAttribute : Attribute
{
    IEnumerable<FieldInfo> fieldInfos = target.GetAllFields();
    foreach( var iField in fieldInfos ){
      object[] customAttributes = iField.GetCustomAttributes(false);
      foreach( var jAttr in customAttributes ){
        if( jAttr.GetType().IsAssignableFrom(typeof(TAttribute)) ){
          closure.Invoke(iField, (TAttribute) jAttr);
        }
      }
    }
}

并像这样称呼它

ReflectionUtils.VisitAnnotatedFields(
  target,
  (FieldInfo field, NotNullAttribute attr) => {
    // do the check for null value and add to failures
  });

作为奖励,它将为您提供额外的强力内部封闭本身。

答案 1 :(得分:1)

如果我正确理解Java的Class<T>(“Class对象代表类型T”,那么.NET中没有对应关系。

.NET无法在编译时限制 Type的实例可能代表什么类型。你必须进行运行时检查:

// using System.Diagnostics.Contracts;

void Foo(Type type)
{
    Contract.Requires(typeof(Attribute).IsAssignableFrom(type));
    // the above allows `type` to represent sub-types of `Attribute` as well.
    // if you want to allow only `Attribute`, change to `type == typeof(Attribute)`. 
    …
}