C# 表达式中的 new Object() 和 new Object{} 有什么区别
What is the difference between new Object() and new Object{} in expressions in C#
我有以下代码片段:
Expression<Func<TSource, TDest>> expression = model => new TDest{};
// Result: {model => new TestModel(){}}
ReSharper 使用 RedundantEmptyObjectOrCollectionInitializer
设置重构此代码段:
Expression<Func<TSource, TDest>> expression2 = model => new TDest();
// Result: {model => new TestModel()}
在那之后,我的代码就不起作用了。花括号对初始化有什么影响?
我在 Stack Overflow 上找到了 What is the Difference Between new object()
and new {}
in C#?,但两个实例看起来是一样的。
expression.GetType().ToString()
等于
expression2.GetType().ToString()
表达式树中的这些初始化有什么区别?:
var a = model => new TDest{};
var b = model => new TDest();
在常规的原始 C# 中,答案是 "nothing"。但是,当涉及表达式树时,就会有所不同;可以看出here
using System;
using System.Linq.Expressions;
public class C<TSource, TDest> where TDest : new() {
public Expression<Func<TSource, TDest>> Foo() => model => new TDest();
public Expression<Func<TSource, TDest>> Bar() => model => new TDest {};
}
编译为:
public Expression<Func<TSource, TDest>> Foo()
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "model");
Expression arg_2E_0 = Expression.New(typeof(TDest));
ParameterExpression[] expr_2A = new ParameterExpression[1];
expr_2A[0] = parameterExpression;
return Expression.Lambda<Func<TSource, TDest>>(arg_2E_0, expr_2A);
}
public Expression<Func<TSource, TDest>> Bar()
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "model");
Expression arg_38_0 = Expression.MemberInit(Expression.New(typeof(TDest)), Array.Empty<MemberBinding>());
ParameterExpression[] expr_34 = new ParameterExpression[1];
expr_34[0] = parameterExpression;
return Expression.Lambda<Func<TSource, TDest>>(arg_38_0, expr_34);
}
因此,其中一个涉及 Expression.MemberInit
(具有一组空的 MemberBinding
元素)以及 Expression.New
。这可能会扰乱任何不期望它的 LINQ 提供程序(或任何类似的 expression-tree 分析)。
ReSharper 在如何实例化 TDest
class.
方面为您提供了更好的建议
理论上,new TDest ()
和 new TDest {}
都会为您提供 TDest
.
的实例,因此没有任何区别
但是,当您使用初始化表达式时,是因为您要设置 TDest
中的 public 个属性或字段的值。
class TDest
{
public string MyProperty { get; set; }
}
因此您可以初始化 TDest
class 并将值设置为 MyProperty
。例如:
// Sample 1
new TDest { MyProperty = "This is the value of my property" };
// Sample 2
new TDest() { MyProperty = "This is the value of my property" };
在你的例子中,你的 class 有一个无参数的构造函数,所以标点符号 {, }
或运算符 ()
都可以。
对于具有无参数构造函数的简单场景,您只能使用 TDest()
缩写形式。
但是如果你有下面的例子class。
class TDest
{
readonly ISomeInterface _someService;
public string MyProperty { get; set; }
public TDest(ISomeInterface someService)
{
_someService = someService;
}
}
并且您想用某些东西而不是它的默认初始化值(null,引用类型)来初始化 MyProperty
,您可以使用完整的对象初始化。例如:
// Sample 3
new TDest(new MySomeServiceImplementation()) { MyProperty = "This is the value of my property" };
希望对您有所帮助!
要有更好的想法,去看看C# Object Initializers。
我有以下代码片段:
Expression<Func<TSource, TDest>> expression = model => new TDest{};
// Result: {model => new TestModel(){}}
ReSharper 使用 RedundantEmptyObjectOrCollectionInitializer
设置重构此代码段:
Expression<Func<TSource, TDest>> expression2 = model => new TDest();
// Result: {model => new TestModel()}
在那之后,我的代码就不起作用了。花括号对初始化有什么影响?
我在 Stack Overflow 上找到了 What is the Difference Between new object()
and new {}
in C#?,但两个实例看起来是一样的。
expression.GetType().ToString()
等于
expression2.GetType().ToString()
表达式树中的这些初始化有什么区别?:
var a = model => new TDest{};
var b = model => new TDest();
在常规的原始 C# 中,答案是 "nothing"。但是,当涉及表达式树时,就会有所不同;可以看出here
using System;
using System.Linq.Expressions;
public class C<TSource, TDest> where TDest : new() {
public Expression<Func<TSource, TDest>> Foo() => model => new TDest();
public Expression<Func<TSource, TDest>> Bar() => model => new TDest {};
}
编译为:
public Expression<Func<TSource, TDest>> Foo()
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "model");
Expression arg_2E_0 = Expression.New(typeof(TDest));
ParameterExpression[] expr_2A = new ParameterExpression[1];
expr_2A[0] = parameterExpression;
return Expression.Lambda<Func<TSource, TDest>>(arg_2E_0, expr_2A);
}
public Expression<Func<TSource, TDest>> Bar()
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "model");
Expression arg_38_0 = Expression.MemberInit(Expression.New(typeof(TDest)), Array.Empty<MemberBinding>());
ParameterExpression[] expr_34 = new ParameterExpression[1];
expr_34[0] = parameterExpression;
return Expression.Lambda<Func<TSource, TDest>>(arg_38_0, expr_34);
}
因此,其中一个涉及 Expression.MemberInit
(具有一组空的 MemberBinding
元素)以及 Expression.New
。这可能会扰乱任何不期望它的 LINQ 提供程序(或任何类似的 expression-tree 分析)。
ReSharper 在如何实例化 TDest
class.
理论上,new TDest ()
和 new TDest {}
都会为您提供 TDest
.
但是,当您使用初始化表达式时,是因为您要设置 TDest
中的 public 个属性或字段的值。
class TDest
{
public string MyProperty { get; set; }
}
因此您可以初始化 TDest
class 并将值设置为 MyProperty
。例如:
// Sample 1
new TDest { MyProperty = "This is the value of my property" };
// Sample 2
new TDest() { MyProperty = "This is the value of my property" };
在你的例子中,你的 class 有一个无参数的构造函数,所以标点符号 {, }
或运算符 ()
都可以。
对于具有无参数构造函数的简单场景,您只能使用 TDest()
缩写形式。
但是如果你有下面的例子class。
class TDest
{
readonly ISomeInterface _someService;
public string MyProperty { get; set; }
public TDest(ISomeInterface someService)
{
_someService = someService;
}
}
并且您想用某些东西而不是它的默认初始化值(null,引用类型)来初始化 MyProperty
,您可以使用完整的对象初始化。例如:
// Sample 3
new TDest(new MySomeServiceImplementation()) { MyProperty = "This is the value of my property" };
希望对您有所帮助!
要有更好的想法,去看看C# Object Initializers。