返回get内部的值和分配属性之间的区别是什么



如果我想为返回任务的非异步方法保留这一点。

public static Task CompletedTaskA { get { return Task.CompletedTask; } }
public static Task CompletedTaskB { get; } = Task.CompletedTask;

在任何情况下,应该优先选择其中一种吗?或者它们是一样的?我也想知道字符串和基本上我对属性所做的任何事情都是一样的,比如:

get {return "some string"; }{ get; } = "some string";

编辑:我想澄清一下我对以上道具的使用。我有几个事件处理程序,它们将Task作为返回类型,由我正在使用的库提供给我。一个这样的事件的例子:

private Task Client_MessageReceived(Message message)
{
Task.Run(async ()=> await HandleMessageReceived(message));
// here is where i would use it
return CompletedTask; // A OR B?
}
private async Task HandleMessageReceived(Message message)
{
// Do stuff with message that might take long and block the handler
}

我的意图是将一个已完成的任务保存在一个字段中(在这种情况下,我选择了一个只读属性(,并继续使用它来满足任务返回。我想知道上面的例子中是否有一个一直在使用相同的已完成任务,而另一个每次都在要求另一个已完成任务?

如果您转到SharpLab并查看以下代码:

public class C 
{
public void M() 
{
}
public string Greetig_1
{
get{return "hello";}
}
public string Greeting_2{get;} = "hello";
}

您可以看到Greeting_2由一个成员变量支持:

public class C
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string <Greeting_2>k__BackingField = "hello";
public string Greeting_1
{
get
{
return "hello";
}
}
public string Greeting_2
{
[CompilerGenerated]
get
{
return <Greeting_2>k__BackingField;
}
}
public void M()
{
}
}

这一直延续到IL级别。由于Greeting_2由成员变量支持,该变量在构造函数中初始化。

在您的Task.CompletedTask示例中,您最终得到的是:

public static Task CompletedTaskB { get; } = Task.CompletedTask;

缓存Task,而:

public static Task CompletedTaskA { get { return Task.CompletedTask; } }

每次调用Task中的CompletedTask对象。事实上,这将由JIT内联。这种方法还有一个优点,即不向类中添加额外的(隐藏的(成员变量,如果您有很多实例并且担心内存使用,这可能会成为一个问题。

它们不一样。每次访问属性get方法时都会调用它。默认情况下,当您创建属性时,它后面会有一个隐藏字段,因此:

public static Task CompletedTaskB { get; set; }

实际上会在幕后产生这个:

private static Task _completedTaskB;
public static Task CompletedTaskB 
{
get {
return _completedTaskB;
} 
set {
_completedTaskB = value;
} 
}

当您分配属性=Task.CompletedTask时,您正在设置其初始值,该值等效于:

_completedTaskB = Task.CompletedTask;

当您访问该属性时,它将从私有字段中读取。

不过我注意到,您将其定义为只读(只有getter而不是setter(,因此无法分配变量。相反,您将不得不使用:

public static Task CompletedTaskA { get { return Task.CompletedTask; } }

这将始终返回Task.CompletedTask。

一般来说,之间的区别

{ get; set; } = "some string";

get {return "some string"; }

第一个是初始赋值,而后者是在访问属性时调用的方法。

当您在定义中将值分配给产权时,一些"魔术"会在幕后发生。编译器创建一个隐藏的后备字段,并在类的构造函数中将该值分配给该后备字段。

换句话说,您可以将下面的两个类视为以相同的方式工作。

class AssignedImplicit {
public string Prop {get;} = "example";
}
class AssignedExplicit {
private readonly string Prop_BackingField;
public AssignedExplicit() {
Prop_BackingField = "example";
}
public string Prop { get { return Prop_BackingField; } }
}

如果只定义一个get方法而不进行赋值,则不会创建backing字段,也不会向构造函数添加任何工作。

对于字符串或任何其他类型都是如此。如果为属性赋值,则构造/获取该值的工作将被放入类的构造函数中。如果您在get方法中创建了值,那么工作就会被放入get方法中。

相关内容

  • 没有找到相关文章

最新更新