我试图在c#中使用DynamicObject,我需要一个动态数组:
var d = new dynamic[];
Run Code Online (Sandbox Code Playgroud)
哪个工作正常.
编辑:请参阅下面的ExpandoObject.
但我也想用这个压缩的初始化新语法用一些数据填充该数组:
var d = new dynamic[] {
new {
Name = "Some",
Number = 1010
},
new {
Name = "Other",
Number = 2010
}
}
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,所有对象都获得非动态类型"对象",并且通过项目的循环将给出一个例外:
foreach (dynamic item in d)
{
@item.Name
@item.Number
}
Run Code Online (Sandbox Code Playgroud)
错误:'object'不包含'Name'的定义.我想我只是以错误的方式初始化数组项.如何添加动态对象?
编辑:新内容:
我意识到"动态"没有动态添加属性的能力.
我最好使用ExpandoObject,它将内部字典中的所有项目公开为属性.但不幸的是,ExpandoObject似乎不支持这种漂亮的压缩创建语法,编译器抱怨:
var d = new ExpandoObject[]{
new ExpandoObject(){
Name="Nnn",
Number=1080
}
}
Run Code Online (Sandbox Code Playgroud)
所以答案可能只是:这是不可能的.
我正在为对象使用对象初始st值设定项:
public class Container
{
public Container () { ContainedItem = new Item; }
public Item ContainedItem { get; set; }
}
public class Item
{
public string Value { get; set; }
}
var MyContainer = new Container()
{
// I want to populate the the property Value of the property Item
// with the second line rather than the first
ContainedItem = new Item() { Value = FooString }, // This works
ContainedItem.Value = FooString // …Run Code Online (Sandbox Code Playgroud) 由于Object Initializers与JSON非常相似,现在.NET中有匿名类型.能够获取字符串(例如JSON)并创建表示JSON字符串的匿名对象会很酷.
使用对象初始值设定项创建匿名类型:
var person = new {
FirstName = "Chris",
LastName = "Johnson"
};
Run Code Online (Sandbox Code Playgroud)
如果您可以传入Object Initializer代码的字符串表示(最好是类似JSON)来创建具有该数据的匿名类型的实例,那将是非常棒的.
我不知道是否可能,因为C#不是动态的,并且编译器实际上将对象初始化器和匿名类型转换为可以运行的强类型代码.本文将对此进行说明.
也许使用JSON并使用它创建键/值Dictionary的功能最有效.
我知道你可以在.NET中将一个对象序列化/反序列化为JSON,但我想要的是一种创建一个基本上松散类型的对象的方法,类似于JavaScript的工作方式.
有谁知道在.NET中这样做的最佳解决方案?
更新:太清楚我为什么要问这个问题的背景......我在考虑C#如何在语言层面(可能)更好地支持JSON,并且我试图想出今天可以做到的方式,从概念上讲原因.所以,我想我会把它发布在这里开始讨论.
我已经使用了很多自动属性但是我已经越来越远离那些使用构造函数中初始化的readonly支持字段设置类.我删除了所有的setter,只有在属性明显需要setter的情况下才添加.
我发现这使得我的课程更加健壮和优雅OO明智而且我正在踢我自己不早点这样做.
我发现构造函数在c#代码示例中一般都没有得到充分利用,我认为自动属性和对象初始化程序是其中的一个重要部分,所以我的问题是为什么c#团队推送这样的功能而不是更多地关注提供最佳功能的功能实践更多.一般来说,我认为编写糟糕的代码太容易了,并且相信可以帮助编码人员编写好的代码
我有兴趣使用该__new__功能将代码注入__init__子类的功能.我从文档中了解到python将调用__init__返回的实例__new__.但是,我__init__在返回它之前更改实例值的努力__new__似乎不起作用.
class Parent(object):
def __new__(cls, *args, **kwargs):
new_object = super(Parent, cls).__new__(cls)
user_init = new_object.__init__
def __init__(self, *args, **kwargs):
print("New __init__ called")
user_init(self, *args, **kwargs)
self.extra()
print("Replacing __init__")
setattr(new_object, '__init__', __init__)
return new_object
def extra(self):
print("Extra called")
class Child(Parent):
def __init__(self):
print("Original __init__ called")
super(Child, self).__init__()
c = Child()
Run Code Online (Sandbox Code Playgroud)
上面的代码打印:
Replacing __init__
Original __init__ called
Run Code Online (Sandbox Code Playgroud)
但我希望它能打印出来
Replacing __init__
New __init__ called
Original __init__ called
Extra called
Run Code Online (Sandbox Code Playgroud)
为什么不?
我觉得Python正在调用原始值__init__ …
当我使用C#中的新对象初始化器初始化对象时,我不能使用类中的一个属性来执行进一步的操作,我不知道为什么.
我的示例代码:
Person person = new Person { Name = "David", Age = "29" };
Run Code Online (Sandbox Code Playgroud)
在Person类中,x将等于0(默认值):
public Person()
{
int x = Age; // x remains 0 - edit age should be Age. This was a typo
}
Run Code Online (Sandbox Code Playgroud)
然而,person.Age确实等于29.我确信这是正常的,但我想明白为什么.
如何在C中重新初始化数组?
我应该通过指针定义它:int *data[]或者我可以只编码:int data[] = {};?
例如,我已将其定义为:
int main(void) {
int data[] = {44, 22, 1, 2, 3, 1000, 3};
Run Code Online (Sandbox Code Playgroud)
现在,我该如何重新初始化阵列data?
这个问题的关键是帮助单元测试.如果我有一个繁忙的__init__(即__init__复杂的初始化),我不能简单地实例化一个类的对象,但我需要模拟/存根调用在依赖关系中的所有方法__init__.
为了说明这个问题,这里是一个例子:
class SomeClass(object):
def __init__(self, dep1, dep2, some_string):
self._dep1 = dep1
self._dep2 = dep2
self._some_string = some_string
# I would need to mock everything here (imagine some even more
# complicated example)
for dep2element in self._dep2:
dep2element.set_dep(dep1)
self._dep1.set_some_string(some_string)
def fun1(self):
...
def fun2(self):
...
def fun3(self):
...
Run Code Online (Sandbox Code Playgroud)
要测试这些fun*功能,每个测试都必须执行复杂的构造.
class TestSomeClass(TestCase):
def create_SomeClass(self, some_string):
dep1 = Mock()
# mock everything required by SomeClass' constructor
dep2 = Mock()
# mock everything required by …Run Code Online (Sandbox Code Playgroud) 我有这个简单的代码:
public static void Main(String[] args)
{
Data data = new Data { List = { "1", "2", "3", "4" } };
foreach (var str in data.List)
Console.WriteLine(str);
Console.ReadLine();
}
public class Data
{
private List<String> _List = new List<String>();
public List<String> List
{
get { return _List; }
}
public Data() { }
}
Run Code Online (Sandbox Code Playgroud)
所以当我创建一个Data类时:
Data data = new Data { List = { "1", "2", "3", "4" } };
Run Code Online (Sandbox Code Playgroud)
该列表中填充了字符串"1","2","3","4",即使它没有set.
为什么会这样?
c# properties object-initializers getter-setter collection-initializer
C#不允许实例字段初始值设定项引用另一个字段.例如,此代码无效:
class A
{
string s1 = "";
string s2 = s1;
}
Run Code Online (Sandbox Code Playgroud)
因为"s2"引用"s1".
但为什么不允许这样做呢?
我的第一个想法是C#规范不保证任何初始化顺序,但根据规范,顺序是声明的顺序:
变量初始值设定项以它们出现在类声明中的文本顺序执行.
因此,如果订单是确定性的,那么这类代码的缺陷可能是什么?
在此先感谢您的帮助.
编辑:
根据Hps,0xA3和Peter的答案:
继承方案中的初始化顺序可能非常混乱,
实现这样的功能需要编译器开发团队的一些资源,但收效甚微,
由于逻辑原因,不可能使用方法或属性(感谢Peter),因此为了保持一致性,字段也是如此.