C#-使新类不是System.Object的一部分

C#-使新类不是System.Object的一部分,c#,inheritance,C#,Inheritance,我有一个庞大的代码库,最近我做了一个更改,将参数的类型从String更改为自定义类。在下一次编译中,我得到了影响所在的所有区域,但是输入类型为Object类型的区域失败了。例如 String str = "32" int i = Convert.ToInt32(str) 现在我已经将String更改为一个新的自定义类型,比如说MyCustomClass,我现在希望下面的代码在下一次编译时失败 MyCustomClass str = new MyCustomClass("32") int i =

我有一个庞大的代码库,最近我做了一个更改,将参数的类型从
String
更改为自定义类。在下一次编译中,我得到了影响所在的所有区域,但是输入类型为
Object
类型的区域失败了。例如

String str = "32"
int i = Convert.ToInt32(str)
现在我已经将
String
更改为一个新的自定义类型,比如说
MyCustomClass
,我现在希望下面的代码在下一次编译时失败

MyCustomClass str = new MyCustomClass("32")
int i = Convert.ToInt32(str)
但它不会转换为
Convert.ToInt32
也接受类型
Object
。是否有某种方法可以更改
MyCustomClass
,使其不再被视为
Object
请注意
Convert.ToInt32
仅用于示例,我还有许多类似的函数,因此请将您的建议/答案集中在所问问题上。

覆盖
ToString()
IConvertible

您在评论中说,您的意图是找到您的对象(以前被视为字符串)现在被视为对象的位置

在这些情况下,第三方代码通常会调用对象上的
.ToString()
,以获取它可以使用的内容。
因此,
Convert.ToInt32(str)
相当于
Convert.ToInt32(str.ToString())

如果实现ToString()和IConvertible以返回旧版本的
str
看起来像什么,那么它应该继续以与旧版本相同的方式工作

可能吧

很抱歉,我知道这不是您想要的100%完美的编译时答案,但我想您也很清楚,您的
MyCustomClass
将始终被视为对象。

覆盖
ToString()
IConvertible

您在评论中说,您的意图是找到您的对象(以前被视为字符串)现在被视为对象的位置

在这些情况下,第三方代码通常会调用对象上的
.ToString()
,以获取它可以使用的内容。
因此,
Convert.ToInt32(str)
相当于
Convert.ToInt32(str.ToString())

如果实现ToString()和IConvertible以返回旧版本的
str
看起来像什么,那么它应该继续以与旧版本相同的方式工作

可能吧


很抱歉,我知道这不是您想要的100%完美的编译时答案,但我想您也很清楚,您的
MyCustomClass
将始终被视为对象。

可能的编译时答案:

  • 编写一个工具,它使用反射来迭代每个系统/第三方DLL中的每个类/结构/接口

  • 输出包含所有这些相同类的CS文件,但只抛出NotImplementedException。
    (T4可以帮助您做到这一点)

  • 将这些类编译成dummy.dll

  • 您的.csproj现在只引用这一个dummy.dll,而不是真正的dll。
    您的项目应该可以针对虚拟dll进行良好编译

  • 查看dummy.cs文件并删除对象的任何用法

  • 重新编译。。。突然间,您会看到大量编译时错误,显示您正在使用对象的任何位置


    • 可能的编译时答案:

      • 编写一个工具,它使用反射来迭代每个系统/第三方DLL中的每个类/结构/接口

      • 输出包含所有这些相同类的CS文件,但只抛出NotImplementedException。
        (T4可以帮助您做到这一点)

      • 将这些类编译成dummy.dll

      • 您的.csproj现在只引用这一个dummy.dll,而不是真正的dll。
        您的项目应该可以针对虚拟dll进行良好编译

      • 查看dummy.cs文件并删除对象的任何用法

      • 重新编译。。。突然间,您会看到大量编译时错误,显示您正在使用对象的任何位置

      实现从MyCustomClass到String的隐式转换

      public static implicit operator string(MyCustomClass str)
      {
          return "Legacy respresentation of str";
      }
      
      这允许编译器选择ToInt32(对象)或ToInt32(字符串),我打赌它更倾向于后者

      这样,所有现有函数调用都将保持不变,因此您不必担心第三方实现细节

      (对不起,我现在不在电脑上,所以我不能测试我的假设是正确的。如果你测试了这个,一定要考虑扩展方法,因为它们会影响攻击者以意想不到的方式做出决定)

      < P>暗示MyCustomClass从一个隐式转换到String。< /P>
      public static implicit operator string(MyCustomClass str)
      {
          return "Legacy respresentation of str";
      }
      
      这允许编译器选择ToInt32(对象)或ToInt32(字符串),我打赌它更倾向于后者

      这样,所有现有函数调用都将保持不变,因此您不必担心第三方实现细节


      (对不起,我现在不在电脑上,所以我不能测试我的假设是正确的。如果你测试这个,一定要考虑扩展方法,因为它们会影响攻击者做出意想不到的方式)

      每种类型都是从对象派生的,你不能改变它。问题是为什么有以对象为参数的方法?为什么不使用类型安全方法?或者泛型等?几乎是重复的@KrikorAilanjian问题,Convert.ToInt32不是他的代码。无法重构基类libraries@user961954你想失败以便修复所有引用,还是真的想让int32转换工作?太棒了,我想我有一个答案。(半答)每个类型都是从object派生的,你不能改变它。问题是为什么有以对象为参数的方法?为什么不使用类型安全方法?或泛型等?几乎是一个重复的问题@KrikorAilanjian,Convert.ToInt32