在以下情况下,我经常遇到一个错误,例如"无法从'方法组'转换为'字符串'"
var list = new List<string>();
// ... snip
list.Add(someObject.ToString);
Run Code Online (Sandbox Code Playgroud)
当然最后一行有一个拼写错误,因为我忘记了之后的调用括号ToString
.正确的形式是:
var list = new List<string>();
// ... snip
list.Add(someObject.ToString()); // <- notice the parentheses
Run Code Online (Sandbox Code Playgroud)
我创建了以下函数:
public void DelegatedCall(Action<Object> delegatedMethod)
Run Code Online (Sandbox Code Playgroud)
并定义了以下方法
public void foo1(String str) { }
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试打电话DelegateCall
时foo1
:
DelegatedCall(foo1);
Run Code Online (Sandbox Code Playgroud)
...我收到以下编译器错误:
Argument 1: cannot convert from 'method group' to 'System.Action<object>'
这个错误的原因是什么,我该如何纠正?不幸的是,铸造foo1
到Action
是不是一种选择.
我对C#语言的一些设计选择感兴趣.有一个在C#规范中的一个规则,允许使用方法组作为表达is
操作:
class Foo {
static void Main() { if (Main is Foo) Main(); }
}
Run Code Online (Sandbox Code Playgroud)
上述条件总是错误的,因为规范说:
7.10.10是运营商
• 如果E是方法组或空文字,如果E的类型是引用类型或可空类型且E的值为null,则结果为false.
我的问题:允许在CLR中使用没有运行时表示的C#语言元素的目的/要点/原因是什么,就像这样的"运行时"运算符中的方法组一样is
?
请考虑以下代码:
var result = IDisposable.Dispose is object; //result equals false
Run Code Online (Sandbox Code Playgroud)
对我(以及我的同事实际上引起我的注意)这个代码的编译感到惊讶.
首先,我的想法IDisposable.Dispose
是以某种方式转换为兼容delegate
.但结果必须是true
因为当然delegate
可以分开object
.
寻找到本说明书中,我发现方法组具有特殊由编译器处理(在的上下文中是操作):
如果E是方法组...结果为false.
纯粹出于好奇,为什么它在规范中?为什么编译器允许它?为什么不抛出编译时错误(比如匿名函数)?
更新:
处理类似的事情时,List<string>
您可以写下以下内容:
list.ForEach(x => Console.WriteLine(x));
Run Code Online (Sandbox Code Playgroud)
或者您可以使用方法组执行相同的操作:
list.ForEach(Console.WriteLine);
Run Code Online (Sandbox Code Playgroud)
我更喜欢第二行代码,因为它对我来说看起来更干净,但这有什么好处吗?
无法分配"AppendText",因为它是"方法组".
public partial class Form1 : Form
{
String text = "";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
String inches = textBox1.Text;
text = ConvertToFeet(inches) + ConvertToYards(inches);
textBox2.AppendText = text;
}
private String ConvertToFeet(String inches)
{
int feet = Convert.ToInt32(inches) / 12;
int leftoverInches = Convert.ToInt32(inches) % 12;
return (feet + " feet and " + leftoverInches + " inches." + " \n");
}
private String ConvertToYards(String inches)
{
int yards = Convert.ToInt32(inches) / …
Run Code Online (Sandbox Code Playgroud) 有什么区别
Class1.Method1<Guid, BECustomer>("cId", Facade.Customers.GetSingle);
Run Code Online (Sandbox Code Playgroud)
和
Class1.Method1<Guid, BECustomer>("cId", x => Facade.Customers.GetSingle(x));
Run Code Online (Sandbox Code Playgroud)
?
Resharper建议使用第一个表达式.
在更新我的UI代码(.NET 4.0应用程序中的C#)时,由于在错误的线程中执行了对UI的调用,我遇到了一个奇怪的崩溃.但是,我已经在主线程上调用了这个调用,所以崩溃没有任何意义:MainThreadDispatcher.Invoke(new Action(View.Method))
崩溃了"调用线程无法访问此对象,因为另一个线程拥有它." 在View属性上.
经过进一步调查,我找到了原因:我是通过方法组调用的.我原以为使用方法组或委托/ lambda基本上是一回事(另见这个问题和这个问题).相反,将方法组转换为委托会导致代码执行,检查值View
.这是立即完成的,即在原始(非UI)线程上,这导致崩溃.如果我使用lambda,则稍后检查属性,从而在正确的线程中完成.
至少可以说,这似乎很有趣.C#标准中有没有提到这个的地方?或者是因为需要找到正确的转换而隐含的?
这是一个测试程序.首先,直接的方式.其次,分两步,更好地说明会发生什么.为了获得额外的乐趣,我Item
在创建委托后进行修改.
namespace ConsoleApplication1 // Add a reference to WindowsBase to a standard ConsoleApplication
{
using System.Threading;
using System.Windows.Threading;
using System;
static class Program
{
static Dispatcher mainDispatcher;
static void Main()
{
mainDispatcher = Dispatcher.CurrentDispatcher;
mainDispatcher.Thread.Name = "Main thread";
var childThread = new Thread(() =>
{
Console.WriteLine("--- Method group ---");
mainDispatcher.Invoke(new Action(Item.DoSomething));
Console.WriteLine("\n--- Lambda ---");
mainDispatcher.Invoke(new Action(() => Item.DoSomething()));
Console.WriteLine("\n--- Method …
Run Code Online (Sandbox Code Playgroud) 我发现了一些非常奇怪的东西,我希望能更好地理解.
var all = new List<int[]>{
new int[]{1,2,3},
new int[]{4,5,6},
new int[]{7,8,9}
};
all.ForEach(n => n.ForEach(i => Console.WriteLine(i)));
Run Code Online (Sandbox Code Playgroud)
可以改写为:
...
all.ForEach(n => n.ForEach(Console.WriteLine));
Run Code Online (Sandbox Code Playgroud)
如何省略lambda表达式参数(i =>)并仍然将当前项传递给console.WriteLine?
感谢您的任何见解.-Keith
几年前,我根据 ReSharper 的一些建议开始使用方法组语法,最近我尝试了ClrHeapAllocationAnalyzer,它标记了我在 lambda 中使用方法组的每个位置的问题HAA0603 - This will allocate a delegate instance
。
由于我很好奇这个建议是否真的有用,我为这两种情况编写了一个简单的控制台应用程序。
代码1:
class Program
{
static void Main(string[] args)
{
var temp = args.AsEnumerable();
for (int i = 0; i < 10_000_000; i++)
{
temp = temp.Select(x => Foo(x));
}
Console.ReadKey();
}
private static string Foo(string x)
{
return x;
}
}
Run Code Online (Sandbox Code Playgroud)
代码2:
class Program
{
static void Main(string[] args)
{
var temp = args.AsEnumerable();
for (int i = 0; i < 10_000_000; i++) …
Run Code Online (Sandbox Code Playgroud)