简体   繁体   English

铸造 object 到没有 generics 的类型

[英]Casting object to type without generics

public class ErrorCode
{
    public int HttpStatus { get; private set; }
    public string JsonErrorCode { get; private set; }
    public Type ExceptionT { get; private set; }

    public ErrorCode(string pJsonErrorCode, int pHttpStatus, Type pExceptionType)
    {
        this.HttpStatus = pHttpStatus;
        this.JsonErrorCode = pJsonErrorCode;
    }

    public void ThrowException(string pMsg)
    {
        throw Activator.CreateInstance(ExceptionT, pMsg);
    }
}

So, as you can see i am trying to create an instance of the given type.因此,如您所见,我正在尝试创建给定类型的实例。 I cannot use Generics.我不能使用 Generics。 because i have a dictionary that creates a pool of error codes.因为我有一个创建错误代码池的字典。

Protocol.ErrorCodes.Add
(
    ErrorCodeType.ElementClickIntercepted,
    new ErrorCode
    (
        "element click intercepted", 
        400, 
        typeof(ElementClickInterceptedException)
    )
);

The above code doesn't work since the type being created is of type object and does not derive from system.exception上面的代码不起作用,因为正在创建的类型是 object 并且不是从 system.exception 派生的

The above code won't work with generics since the dictionary needs to understand what is being built.上面的代码不适用于 generics 因为字典需要了解正在构建的内容。 I am not sure what to do here.我不确定在这里做什么。 my dictionary has about 50 different exceptions.我的字典有大约 50 个不同的例外。 Thoughts?想法?

You need to cast the instance created to Exception您需要将创建的实例转换为 Exception

public class ErrorCode
{
  public int HttpStatus { get; private set; }
  public string JsonErrorCode { get; private set; }
  public Type ExceptionT { get; private set; }

  public ErrorCode(string pJsonErrorCode, int pHttpStatus, Type pExceptionType)
  {
    this.HttpStatus = pHttpStatus;
    this.JsonErrorCode = pJsonErrorCode;
    this.ExceptionT = pExceptionType;
  }

  public void ThrowException(string pMsg)
  {
    throw (Exception)Activator.CreateInstance(ExceptionT, pMsg);
  }
}

You can replace Exception by ElementClickInterceptedException or anything needed.您可以将Exception替换为ElementClickInterceptedException或任何需要的东西。

Test测试

var error = new ErrorCode("test", 1, typeof(ArgumentException));
try
{
  error.ThrowException("error");
}
catch ( Exception ex )
{
  Console.WriteLine(ex.Message);
}

Fiddle Snippet小提琴片段

Output Output

error

I cannot use Generics.我不能使用 Generics。 because i have a dictionary that creates a pool of error codes.因为我有一个创建错误代码池的字典。

Yes, you really can, and it is the right solution.是的,你真的可以,而且这是正确的解决方案。 You just need to declare a base interface for your lookup dictionary.您只需要为查找字典声明一个基本接口。

public interface IErrorCode
{
    int HttpStatus { get; }
    string JsonErrorCode { get; }
    void ThrowException(string pMsg);
}

public class ErrorCode<T> : IErrorCode where T : Exception
{
    public int HttpStatus { get; private set; }
    public string JsonErrorCode { get; private set; }

    public ErrorCode(string pJsonErrorCode, int pHttpStatus)
    {
        this.HttpStatus = pHttpStatus;
        this.JsonErrorCode = pJsonErrorCode;
    }

    public void ThrowException(string pMsg)
    {
        var exception = (T)Activator.CreateInstance
        (
            typeof(T), 
            new object[] { pMsg }
        );
        throw exception;
    }
}


//Declare the dictionary with the interface, not the concrete type
Protocol.ErrorCodes = new Dictionary<ErrorCodeType,IErrorCode>();

Protocol.ErrorCodes.Add
(
    ErrorCodeType.ElementClickIntercepted,
    new ErrorCode<ElementClickInterceptedException>
    (
        "element click intercepted", 
        400
    )
);

If you need to work with any element in the list, you can use the interface-- you should not have to cast anything.如果您需要处理列表中的任何元素,您可以使用该界面——您不必强制转换任何内容。

To get the HTTP status:获取 HTTP 状态:

var status = Protocol.ErrorCodes[key].HttpStatus;

To get the Json error code:获取 Json 错误代码:

var errorCode = Protocol.ErrorCodes[key].JsonErrorCode;

In general your code should not be depending on concrete instances but on interfaces (per the "D" in SOLID ).通常,您的代码不应依赖于具体实例,而应依赖于接口(根据SOLID中的“D”)。

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

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