C# 功能(例外情况除外)是否与功能B相同<;T>;(T ex)其中T:例外?

C# 功能(例外情况除外)是否与功能B相同<;T>;(T ex)其中T:例外?,c#,generics,C#,Generics,关于泛型的两个简单问题 以下两个函数定义是否相同 FunctionA(Exception ex); FunctionB<T>(T ex) where T : Exception; FunctionA(例外情况除外); 函数b(T ex),其中T:异常; 通用实现(FunctionB)是否比普通实现(FunctionA)有优势?以下内容实际上是相同的(结果): 但如果你这样做,情况就不一样了: catch (ApplicationException e) { Functi

关于泛型的两个简单问题

以下两个函数定义是否相同

FunctionA(Exception ex);

FunctionB<T>(T ex) where T : Exception;
FunctionA(例外情况除外);
函数b(T ex),其中T:异常;

通用实现(FunctionB)是否比普通实现(FunctionA)有优势?

以下内容实际上是相同的(结果):

但如果你这样做,情况就不一样了:

catch (ApplicationException e)
{
    FunctionB(e);
}
catch (Exception e)
{
    FunctionA(e);
}
这是因为FunctionB在编译时被类型化为ApplicationException,而对FunctionA的调用总是将参数向下转换为Exception。根据FunctionB的实现情况,这可能无关紧要,但在某些情况下,它可能会产生影响。根据经验,如果您的方法实现不需要泛型实现,那么就不要使用它

以下是一些重要的例子:

public T AddSomeContextToThisException<T>(T ex) where T : Exception
{
    ex.Data.Add("Some key", "Some context message");
    return ex;
}

public T ThisIsABadIdeaForExceptionsButMaybeAGoodIdeaForOtherTypes<T>(T ex) where T : Exception, new()
{
    // do something with ex

    return new T();
}
public T AddSomeContextToThisException(T ex),其中T:Exception
{
例如Data.Add(“某个键”、“某个上下文消息”);
退换货;
}
公共T这是异常的定义,但也可能是其他类型的定义(T ex),其中T:Exception,new()
{
//和前男友做点什么
返回新的T();
}
以下示例需要一些用于上下文的附加代码,因此请参见下面的代码:

private readonly Bar bar = new Bar();

public void HandExceptionOffToSomethingThatNeedsToBeStronglyTyped<T>(T ex) where T : Exception
{
    ICollection<T> exceptions = bar.GetCollectionOfExceptions<T>();
    exceptions.Add(ex);

    // do other stuff
}

public class Bar
{
    // value is object, because .net doesn't have covariance yet
    private Dictionary<Type, object> listsOfExceptions = new Dictionary<Type, object>();

    public ICollection<T> GetCollectionOfExceptions<T>()
    {
        if (!listsOfExceptions.ContainsKey(typeof(T)))
        {
            listsOfExceptions.Add(typeof(T), new List<T>());
        }
        return listsOfExceptions[typeof(T)] as List<T>;
    }
}
private readonly Bar=new Bar();
public void handexceptionofftosomething需要强类型化(T ex),其中T:Exception
{
ICollection exceptions=bar.GetCollectionOfExceptions();
例外情况。添加(ex);
//做其他事情
}
公共类酒吧
{
//值是对象,因为.net还没有协方差
private Dictionary listsOfExceptions=新建字典();
公共ICollection GetCollectionOfExceptions()
{
if(!listsOfExceptions.ContainsKey(typeof(T)))
{
添加(typeof(T),new List());
}
将listsOfExceptions[typeof(T)]作为列表返回;
}
}

以下内容实际上是相同的(结果):

但如果你这样做,情况就不一样了:

catch (ApplicationException e)
{
    FunctionB(e);
}
catch (Exception e)
{
    FunctionA(e);
}
这是因为FunctionB在编译时被类型化为ApplicationException,而对FunctionA的调用总是将参数向下转换为Exception。根据FunctionB的实现情况,这可能无关紧要,但在某些情况下,它可能会产生影响。根据经验,如果您的方法实现不需要泛型实现,那么就不要使用它

以下是一些重要的例子:

public T AddSomeContextToThisException<T>(T ex) where T : Exception
{
    ex.Data.Add("Some key", "Some context message");
    return ex;
}

public T ThisIsABadIdeaForExceptionsButMaybeAGoodIdeaForOtherTypes<T>(T ex) where T : Exception, new()
{
    // do something with ex

    return new T();
}
public T AddSomeContextToThisException(T ex),其中T:Exception
{
例如Data.Add(“某个键”、“某个上下文消息”);
退换货;
}
公共T这是异常的定义,但也可能是其他类型的定义(T ex),其中T:Exception,new()
{
//和前男友做点什么
返回新的T();
}
以下示例需要一些用于上下文的附加代码,因此请参见下面的代码:

private readonly Bar bar = new Bar();

public void HandExceptionOffToSomethingThatNeedsToBeStronglyTyped<T>(T ex) where T : Exception
{
    ICollection<T> exceptions = bar.GetCollectionOfExceptions<T>();
    exceptions.Add(ex);

    // do other stuff
}

public class Bar
{
    // value is object, because .net doesn't have covariance yet
    private Dictionary<Type, object> listsOfExceptions = new Dictionary<Type, object>();

    public ICollection<T> GetCollectionOfExceptions<T>()
    {
        if (!listsOfExceptions.ContainsKey(typeof(T)))
        {
            listsOfExceptions.Add(typeof(T), new List<T>());
        }
        return listsOfExceptions[typeof(T)] as List<T>;
    }
}
private readonly Bar=new Bar();
public void handexceptionofftosomething需要强类型化(T ex),其中T:Exception
{
ICollection exceptions=bar.GetCollectionOfExceptions();
例外情况。添加(ex);
//做其他事情
}
公共类酒吧
{
//值是对象,因为.net还没有协方差
private Dictionary listsOfExceptions=新建字典();
公共ICollection GetCollectionOfExceptions()
{
if(!listsOfExceptions.ContainsKey(typeof(T)))
{
添加(typeof(T),new List());
}
将listsOfExceptions[typeof(T)]作为列表返回;
}
}

在函数内部,没有区别。区别来自外部。如果使用泛型函数,则可以将相同类型的异常返回给调用代码,而不是基本的
异常。但在大多数情况下,这是一个没有实际意义的问题。

在函数内部,没有区别。区别来自外部。如果使用泛型函数,则可以将相同类型的异常返回给调用代码,而不是基本的
异常。但在大多数情况下,这是一个没有实际意义的问题。

请参见以下问题:
见这个问题:

与FunctionA相比,FunctionB没有多少优势。然而,两者之间有着明显的区别

使用FunctionA,可以将派生自(或是)异常的任何类型传递到函数中

使用FunctionB,可以将从T派生的任何类型(必须从T派生或是异常)传递到函数中

这意味着,根据T的类型,您将有一个更专门的参数,它将限制您可以传递给它的类型,因为该参数将被类型化为T,而不是异常

现在,如果T是一个例外,那么没关系,函数是相同的。但是,如果T是InvalidOperationException,则只允许InvalidOperationException的实例(以及从中派生的类)


当您希望确保类型的专门化而不必求助于不提供所需专门化级别的基类时,这通常是您想要的。

与FunctionA相比,FunctionB没有多少优势。然而,两者之间有着明显的区别

使用FunctionA,可以将派生自(或是)异常的任何类型传递到函数中

使用FunctionB,可以将从T派生的任何类型(必须从T派生或是异常)传递到函数中

这意味着,根据T的类型,您将有一个更专门的参数,它将限制您可以传递给它的类型,因为该参数将被类型化为T,而不是异常

现在,如果T是一个例外,那么没关系,函数是相同的。但是,如果T是InvalidOperationException,则只有InvalidOperationException的实例