简体   繁体   English

什么是像Class这样的参数化类型的等效C# <? extends Throwable> 在Java中?

[英]What is the equivalent C# of a parameterized type like Class<? extends Throwable> in Java?

I wrote this blog: http://tri-katch.blogspot.com and implemented the pahakia-fault library: https://github.com/pahakia/lib . 我写了这个博客: http ://tri-katch.blogspot.com并实现了pahakia-fault库: https : //github.com/pahakia/lib

I'd like to convert the pahakia-fault library to C#. 我想将pahakia-fault库转换为C#。 But how to translate the following into C#? 但是如何将以下内容转换为C#?

public CodeBlockWorker<T> ignore(Class<? extends Throwable> clazz,
        @SuppressWarnings("unchecked") Class<? extends Throwable>... classes) {
    String[] codes = new String[classes.length];
    for (int i = 0; i < codes.length; i++) {
        Class<? extends Throwable> clz = classes[i];
        codes[i] = clz.getName();
    }
    handlers.add(new KatchHandler<T>(clazz.getName(), codes));
    return this;
}

I know C# has Type as the equivalent of Class in Java but Type is not parameterized. 我知道C#具有Type作为Java中Class的等效项,但是Type没有参数化。

So how to represent a parameterized type in C# if I want to use the type itself instead of an instance of it? 因此,如果我想使用类型本身而不是实例,该如何在C#中表示参数化类型?

Thanks. 谢谢。

My java is a bit rusty, but I think what you are trying to accomplish can be done by using the GetType method to get the type of the passed parameters: 我的Java有点生锈,但是我认为您可以尝试通过使用GetType方法获取传递的参数的类型来完成:

public CodeBlockWorker<T> Ignore(
      Exception clazz, params Exception[] classes)
{

    handlers.add(
       new KatchHandler<T>(
           //You can use FullName if you want to include the namespace
           clazz.GetType().Name, 
           classes.Select(t => t.GetType().Name)
           /* might need to call .ToArray() if your Constructor expects an array */);

    return this;
}

Right so a bit about what's going on. 正确一点,这是怎么回事。 As any "throwable" exception (ie one that can be used in a try/catch) in .Net must inherit from Exception you can set your method parameters to use Exception . 由于.Net中的任何“可抛出”异常(即可以在try / catch中使用的Exception )都必须继承自Exception ,因此可以将方法参数设置为使用Exception The params keyword is just a hint to the compiler that allows multiple method parameters to be automatically passed as an array. params关键字只是对编译器的提示,它允许多个方法参数作为数组自动传递。

Object in .net has the method GetType which will return the Type for that instance. .net中的Object具有方法GetType ,它将返回该实例的Type。 You can that get either just the class name via Name or the class name and namespace via FullName . 您可以通过Name获得类名,也可以通过FullName获得类名和名称空间。 You can also use the keyword typeof to get the Type of a generic parameter. 您还可以使用关键字typeof获取通用参数的类型。

Finally a bit of linq goodness with the .Select method, which performs a transformation / projection over an enumerable (ie array), in this case returning an enumerable of every name in classes . 最后, .Select方法具有一些linq的优点,该方法在可枚举(即数组)上执行转换/投影,在这种情况下,返回classes中每个名称的可枚举。

Update 更新

If you are trying to work on Types instead of instances of exceptions you could also try and write your method using generic type parameters and the typeof keyword to get the type of the type parameters: 如果您尝试使用类型而不是异常实例,则还可以尝试使用泛型类型参数和typeof关键字编写方法以获取类型参数的类型:

 public CodeBlockWorker<T> Ignore<TClazz, TClasses>()
    where TCLazz : Exception
    where TClasses : Exception
 {
     var typename = typeof(TClazz).Name;
 }

The where clauses force the caller to pass in an exception class: where子句强制调用者传递异常类:

 Ignore<NullReferenceException, ArgumentException>();

If you wanted to allow the caller to put multiple TClasses you'd have to create additional method overloads for each additional type (which is how this is done for Action : 如果要允许调用方放置多个TClasses ,则必须为每种其他类型创建其他方法重载(这是对Action的完成方式:

 Ignore<TClazz, T1, T2>(){}
 Ignore<TClazz, T1, T2, T3>(){}

However, you could have each of these overrides feed into the same method: 但是,您可以将这些替代中的每一个都馈入同一方法:

 private CodeBlockWorker<T> DoWork(Type TClazz, params Type[] TClasses){}
 public CodeBlockWorker<T> Ignore<TClazz, T1, T2, T3>()
 {
     return DoWork(typeof(TClazz), typeof(T1), typeof(T2), typeof(T3));
 }

Or you could write it such that the caller has to pass in types, but there isn't a way to restrict the values passed in at compile time; 或者,您可以编写它以便调用者必须传入类型,但是没有一种方法可以限制在编译时传入的值。 just as you can't create a method that has an integer parameter that restricts the value to '5' and '42'; 就像您无法创建具有整数参数的方法一样,该方法将值限制为“ 5”和“ 42”; you can only do this at run time. 您只能在运行时执行此操作。

Ignore(Type clazz, params Type[] classes){

    var typename = clazz.Name;
}

This would be called as: 这称为:

Ignore(
    typeof(NullReferenceException), 
    typeof(ArgumentException), 
    typeof(DivideByZeroException));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM