如何动态地向类中添加属性

3
我想创建一个错误类,它具有一些静态属性,例如: MessageInnerExceptionStacktraceSource。但是我想添加一些动态属性。
如果异常是 FileNotFoundException,我想添加 FileName 属性。
或者如果它是 SqlException,我想添加 LineNumber 属性。但我不能从 Exception 继承该类,因为我将从 Web 服务返回该类。我该如何做到这一点?
6个回答

2

C#是一种静态类型语言。这意味着通常情况下你不能在运行时动态地向类中添加属性,除非进行某些非常奇怪的IL注入(这是你肯定要避免的)。

在你的情况下,似乎你需要更好地理解异常——我们通常抛出特定类型的异常来指示异常问题的原因。例如,如果你正在寻找一个文件但它不存在,你会抛出一个FileNotFoundException;如果有一些应用程序特定的问题,你可以创建自己的异常类并抛出该异常。

请记住,异常应该是异常的。


你听说过匿名类型吗? - Lucas B
是的,我听说过 - 但你无法创建匿名异常。 - Jaco Pretorius

2

不要试图让C#处理它目前无法很好处理的事情,我建议您采取一种稍微不同的方法。

为什么不将这些额外属性作为字典中的数据添加进去?您的类可以公开一个接口来获取“属性”(在单词的一般意义上),即键,然后您的调用代码可以检查这些属性并根据需要使用它们来查找值。


1

你可以使用C#的新特性,如匿名类型,动态地创建类型。

我不确定你是否正在尝试做类似的事情,但可以按照以下方式实现要求。

        public interface IError { }

        public class ErrorTypeA : IError
        { public string Name; }

        public class ErrorTypeB : IError
        {
            public string Name;
            public int line;
        }

        public void CreateErrorObject()
        {
            IError error;
            if (FileNotFoundException) // put your check here
            {
                error = new ErrorTypeA
                    {
                        Name = ""
                    };
            }
            elseif (InValidOpertionException) // put your check here
            {
                error = new ErrorTypeB
                {
                    Name = "",
                    line = 1
                };
            }
        }

希望这能帮到你。

那么你正在捕获异常并将其包装起来??这是处理异常的非常糟糕的方式(调用代码将始终需要检查返回值并处理异常)。这使得消费者代码比它应该的更加棘手。 - Jaco Pretorius
抱歉,我误解了您的问题。请再次提供需要翻译的内容。 - Asad

1

我的建议是使用一个字典来存储所有的额外数据。

public class Logging
{
    private Dictionary<string, string> _ExtraInfo = new Dictionary<string, string>();

    public Dictionary<string, string> ExtraInfo {
        get { return _ExtraInfo; }
        set { _ExtraInfo = value; }
    }

}

使用方法:

   Logging MyLogger = new Logging();
   MyLogger.ExtraInfo.Add("Filename", thefilename);
   MyLogger.ExtraInfo.Add("ClientTime", now);

等等。


0

你的目标非常不清晰。请重新考虑设计,使用非静态类和继承。

同时,请记住在 .NET BCL 中有许多现成的异常类可供使用,你需要好好利用它们。


0
创建一个新的异常类型,派生自 Exception。抛出此异常,并将 InnerException 属性设置为引起混乱的异常。
您可以检查内部异常的类型并相应地显示数据。
如果可能的话,您当然也可以只是 throw 原始异常,让调用者处理它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接