gpt4 book ai didi

.net - 构造函数优先

转载 作者:行者123 更新时间:2023-12-04 06:15:05 25 4
gpt4 key购买 nike

我必须根据构造函数的参数构建一个特殊的类行为。假设 Foo 绘图应该永远是绿色的,如果它是用绿色铅笔构建(绘制)的。
如果使用任何铅笔,Foo 应该是透明的...

现在,看看下面的代码。是否有可能修改构造函数“看到”传入参数对象的真实类型的“输出”? (实际上它们都是“对象”):

class Program
{
static void Main(string[] args)
{
object[] objs = { new IndexOutOfRangeException(), MyEnum.Beta, 45, new AssemblyName(), new { Name = "a" } };

for (int i = 0; i < objs.Length; i++)
{
Console.WriteLine("{0} => {1} ", i, objs[i]);
}
Console.WriteLine("=========================== ");
for (int i = 0; i < objs.Length; i++)
{
Foo myFoo = new Foo(objs[i]);
Console.WriteLine("{0} => {1}", i, myFoo);
}
}
}

public class Foo
{
object value;
string typeName;

public Foo(object obj)
{
value = obj;
typeName = "object";
}

public Foo(MyEnum enm)
{
value = enm;
typeName = "MyEnum";
}

public Foo(int myInt)
{
value = myInt;
typeName = "int";
}

public Foo(Exception ex)
{
value = ex;
typeName = "exception";
}

public override string ToString()
{
return string.Format("FOO (object = '{0}'; type = '{1}')", value, typeName);
}
}

public enum MyEnum
{
Alpha,
Beta
}

输出
0 => System.IndexOutOfRangeException: Index was outside the bounds of the array.
1 => Beta
2 => 45
3 =>
4 => { Name = a }

===========================

0 => FOO (object = 'System.IndexOutOfRangeException: Index was outside the bound
s of the array.'; type = 'object')
1 => FOO (object = 'Beta'; type = 'object')
2 => FOO (object = '45'; type = 'object')
3 => FOO (object = ''; type = 'object')
4 => FOO (object = '{ Name = a }'; type = 'object')

编辑:

正如看到的一些答案,我想强调的是,这与要在“类型”变量中显示的正确字符串无关,例如使用 value.GetType() ,但问题是关于“进入”正确的构造函数。

换句话说, 为什么编译器没有检测到正确的类型并将其“重定向”到正确的构造函数?

编辑 2:

正如回答者所提到的,构造函数的“方式”是在编译时“构建”的,而不是在运行时。说一个像他这样的代码
MyEnum en = MyEnum.Beta;
Console.WriteLine("Enum example: obj:{0} Foo:{1}", en, new Foo(en));

将输出“好”的输出:
Enum example: obj:Beta Foo:FOO (object = 'Beta'; type = 'MyEnum')

所以......显然,有什么方法可以“绕过”这种行为,但构造函数中的运行时检测,就像提议的里德科普西......?!

最佳答案

Why does the compiler not detect the correct type and "redirects" it to the correct constructor?



这是因为您将对象作为 System.Object 传入. ( object[] objs = { n... ) 构造函数是在编译时选择的,而不是在运行时选择。编译器可以看到所用变量的声明,并用于检查适当的类型。

正如您在另一条评论中提到的:

ok, what if I have a big array of objects, and don't know, a priori their type?



这正是编译器以这种方式工作的原因。它无法在编译时知道您想要哪个构造函数,并且因为您有 System.Object有效的构造函数,它被选中。

如果您想分别处理这些特定类型,但仍将对象构造为 System.Object ,您必须在对象的构造函数内部添加检查,并分别处理特定情况。但是,如果您这样做,这不是最易于维护的代码。
public Foo(object obj)
{
value = obj;
typeName = "object";

// Change typeName if appropriate
if (obj != null)
{
if (obj is MyEnum)
typeName = "MyEnum";
else if (obj is int)
typeName = "int";
else if (obj is Exception)
typeName = "exception";
}
}

编辑:

鉴于在您的实际代码中,构造函数可能会做更多的工作,我会考虑制作一个工厂方法来处理这个问题。它允许您使用与上述类似的方法,但保留类型安全的构造函数:
// I'd make the object constructor private, to prevent accidental usage:
private Foo(object obj) { ...

public static Foo CreateAppropriateFoo(object obj)
{
if (obj == null)
return new Foo(obj); // Use object constructor
else
{
if (obj is MyEnum)
return new Foo( (MyEnum)obj );
else if (obj is int)
return new Foo( (int)obj );
else if (obj is Exception)
return new Foo( (Exception)obj );
}
}

这至少可以防止构造函数逻辑的重复,并使运行时发生一些逻辑更加明显。

关于.net - 构造函数优先,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7351118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com