Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在get中返回值与指定属性之间有什么区别?_C#_.net_Asynchronous_Properties_Task - Fatal编程技术网

C# 在get中返回值与指定属性之间有什么区别?

C# 在get中返回值与指定属性之间有什么区别?,c#,.net,asynchronous,properties,task,C#,.net,Asynchronous,Properties,Task,如果我想为返回任务的非异步方法保留这个便利 public static Task CompletedTaskA { get { return Task.CompletedTask; } } public static Task CompletedTaskB { get; } = Task.CompletedTask; 在任何情况下,其中一个应该优先于另一个吗?或者它们是一样的?我还想知道字符串和基本上我对属性所做的任何事情也是如此,例如: get{return“some string”;}v

如果我想为返回任务的非异步方法保留这个便利

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

public static Task CompletedTaskB { get; } = Task.CompletedTask;
在任何情况下,其中一个应该优先于另一个吗?或者它们是一样的?我还想知道字符串和基本上我对属性所做的任何事情也是如此,例如:

get{return“some string”;}
vs
{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
}
我的意图是将已完成的任务保存在一个字段中(在本例中,我选择了一个只读属性),并继续使用它来满足任务返回。我想知道上面的例子中是否有一个一直在使用同一个已完成的任务,而另一个每次都要求另一个已完成的任务?

它们不一样。 每次访问时都会调用properties 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";


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

当您在定义中为属性权限赋值时,一些“魔法”在幕后发生。 编译器创建一个隐藏的支持字段,并在类的构造函数中将该值分配给该支持字段

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

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方法而不进行赋值,则不会创建支持字段,也不会向构造函数添加任何工作

这适用于字符串或任何其他类型。 如果为属性赋值,则构造/获取该值的工作将放入类的构造函数中。如果在get方法中创建值,则工作将放入get方法。

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

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()
    {
    }
}
公共C类
{
[编译生成]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
私有只读字符串k\uu BackingField=“hello”;
公共字符串问候语\u 1
{
得到
{
回复“你好”;
}
}
公共字符串问候语2
{
[编译生成]
得到
{
返回k__BackingField;
}
}
公屋
{
}
}
这一直延续到IL水平。由于
Greeting_2
由一个成员变量支持,该变量在构造函数中初始化

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

publicstatictaskcompletedtaskb{get;}=Task.CompletedTask

缓存
任务
,而:

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


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

您是否尝试搜索现有的解决方案?这个有很多重复的
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()
    {
    }
}