我有下面的方法将一个(非静态的)MethodInfo转换为一个编译后的表达式(Func),然后可以调用它。
这很好用:我可以使用同时包含引用对象和值类型的方法来调用它。
但是与原始方法不同,在原始方法中,我可以调用一个参数,该参数期望a double并将其传递给该方法,而int此编译表达式不支持该方法,并抛出InvalidCastException。
如何修改它以支持正常方法调用期间发生的相同类型的隐式转换?
额外的问题:instanceExp是否应使用DeclaringType或中ReflectedType的MethodInfo?
public Func<object, object[], object> Create(MethodInfo methodInfo)
{
var methodParams = methodInfo.GetParameters();
var arrayParameter = Expression.Parameter(typeof(object[]), "array");
var arguments =
methodParams.Select((p, i) => Expression.Convert(
Expression.ArrayAccess(arrayParameter, Expression.Constant(i)), p.ParameterType))
.Cast<Expression>()
.ToList();
var instanceParameter = Expression.Parameter(typeof(object), "controller");
var instanceExp = Expression.Convert(instanceParameter, methodInfo.DeclaringType);
var callExpression = Expression.Call(instanceExp, methodInfo, arguments);
var bodyExpression = Expression.Convert(callExpression, typeof(object));
return Expression.Lambda<Func<object, object[], object>>(
bodyExpression, instanceParameter, arrayParameter)
.Compile();
}
Run Code Online (Sandbox Code Playgroud)
-编辑 …
有没有人为.NET制作/制造/销售容错的XML阅读器?
是的,我知道,XML并不是设计成有错误的,如果它无效则应该被拒绝......等等.但遗憾的是现实世界并不完美,开发人员确实犯了错误,我仍然希望能够阅读他们的提要,即使我在这里或那里错过了奇怪的元素,因为它没有正确编码或者在其中有其他错误. 所以请,没有答案"修复源"或"拒绝它".
那么,有没有人能够恢复和处理XML文件中的常见错误?
当处理一个包含none,一个或多个项的枚举时,foreach循环可以很容易地迭代它们,LINQ Select可以很容易地从枚举项目中项目.
foreach (var attr in p.GetCustomAttributes().OfType<A>()) ...
Run Code Online (Sandbox Code Playgroud)
当处理包含none或只有一个项目的枚举时,事情会有点棘手.您可以使用相同的foreach循环,但不能确保只存在其中一个项目,并且它可能会执行多次.
您可以添加.Take(1)以清楚地表明您只需要一个并确保循环仅执行一次.但如果不止一个,那就不会抛出异常.
foreach (var attr in ...().Take(1)) ...
Run Code Online (Sandbox Code Playgroud)
您可以事先添加一个检查,以确保只有一个,或者可能是一个新的代码合同来检查,但这是相当混乱的:
Contract.Requires(p..GetCustomAttributes().OfType<A>().Count() < 2);
foreach (var attr in p.GetCustomAttributes().OfType<A>()) ...
Run Code Online (Sandbox Code Playgroud)
您甚至可以创建一个新的扩展方法.ZeroOrOne<T>(),它返回枚举中的第一个元素,然后如果您要求更多,则抛出异常.
foreach (var attr in ...().ZeroOrOne()) ...
Run Code Online (Sandbox Code Playgroud)
或者你可以摆脱循环,使用.SingleOrDefault()然后测试null,这在意图方面显然是最清楚的,并确保循环执行零次或一次但是更多的代码,它不那么"声明性"而且它不是"可组合":
var attr = p.GetCustomAttributes().OfType<A>().SingleOrDefault();
if (attr != null)
{
...
Run Code Online (Sandbox Code Playgroud)
那么问题是:人们更喜欢上述哪种(或其他建议)?为什么? 大多数习惯于程序代码的程序员自然会更喜欢这个if语句,但对于那些深入到函数式编程的人来说,你有更好的方法吗?
其他一些语言有清晰的技术来处理这个问题,例如F#的数组模式可以匹配零个,一个或多个,或者失败.是否存在foroneC#语言中的构造的情况,它等同于检查枚举中是否有零或一个然后执行它?
[这里的具体示例是获取自定义属性,其中属性已被标记为不允许多个,但问题更一般地是关于处理零/一个案例.]
从ASMX服务返回的对象在Silverlight应用程序中使用.类具有方法,但ASMX WebMethod的结果不显示对象的方法.
这是我的课
public class Dog
{
public string Name{get;set;}
public void Bark();
}
Run Code Online (Sandbox Code Playgroud)
这是WebMethod
[WebMethod]
public List<Dog> Findlabrador()
{
blah blah blah
return list_of_labrador;
}
Run Code Online (Sandbox Code Playgroud)
银光代码
void LabradorFetchCompleted(object sender, LabradorFetchCompletedEventArgs e)
{
var list_of_labrador = e.Result;
foreach(var labradorDog in list_of_labrador)
{
labradorDog.Bark();
//** WTH my labrador can't BARK** Bark method is not shown in intellisense there is compilation error if i explicitly specify
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,嗯,让我说出你的话.以下是重现问题的步骤
创建一个Silverlight应用程序项目(让VS创建网站来托管应用程序)
创建一个Silverlight类库,在其中创建Dog类
将Silverlight类库编译为assembly(Dog.dll)
将Dog.dllsilverlight程序集的引用添加到silverlight应用程序项目中
将WebService应用程序添加到项目中(DogService.asmx注意asmx …
我正在尝试学习信号器,这个错误我已经成立了.
无法读取未定义的属性'chatHub'.
$(document).ready(function () {
var chat = $.connection.chatHub;
$.connection.hub.start();
});
Run Code Online (Sandbox Code Playgroud)
和hub文件是:
namespace TestSignalR.Web.Hubs
{
public class ChatHub : Microsoft.AspNet.SignalR.Hub
{
public void Send(string msg)
{
ChatData chat = new ChatData();
chat.Msg = msg;
chat.UserName = HttpContext.Current.User.Identity.Name;
chat.Date = "? at " + DateTime.Now.ToString("hh:mm tt");
Clients.All.broadCastMessage(chat);
}
}
}
Run Code Online (Sandbox Code Playgroud) 我在C#中的类中使用了一个索引器,但我想知道默认情况下是否有用于制作索引器的快捷方式(例如' cwtab tab' Console.WriteLine()).有谁知道这是否存在?
这是"Person"类的代码(带索引器):
public string SurName { get; set; }
public string FirstName { get; set; }
public string Birthplace { get; set; }
public string this[int index]
{
set
{
switch (index)
{
case 0:
this.SurName = value;
break;
case 1:
this.FirstName = value;
break;
case 2:
this.Birthplace = value;
break;
default:
throw new ArgumentOutOfRangeException("index");
}
}
get
{
switch (index)
{
case 0: return this.SurName;
case 1: return this.FirstName;
case 2: return this.Birthplace;
default: …Run Code Online (Sandbox Code Playgroud) c# ×6
.net ×1
asmx ×1
asp.net-mvc ×1
class ×1
ienumerable ×1
indexer ×1
jquery ×1
rss ×1
signalr ×1
signalr-hub ×1
silverlight ×1
web-services ×1
windows ×1
winforms ×1
xml ×1