关于匿名类的访问问题,100分求助

蓝色_冰点 2016-03-09 06:16:34
C#中匿名类的访问范围是不能跨程序集的,如A.dll中有方法 void ClassA.Method(object p)
那么如果在B.dll中调用 ClassA.Method(new { name="XXX" })就会出错。

那么。。。。在MVC项目中很常见的代码:

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/id");

routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{*pathInfo}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } //这里是怎么识别这个匿名类的?
);
}
}


又或者:

@Html.TextBox("name", "value", new { style = "font-size:12px" })

这些又是怎么能识别这些匿名类的?
...全文
477 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
software_artisan 2016-03-12
  • 打赏
  • 举报
回复
如果知道类型属性,直接定义一个类型然后强制转换就ok。如果不知道类型属性,那就只能反射了。
Icedmilk 2016-03-11
  • 打赏
  • 举报
回复
匿名类背后是泛型,是强类型,整个C#就没有弱类型的概念 如果你定义 var v = new { a = "1", b = 2, c = false }; 那么v的类型就是 XXX<string, int, bool> 因为每个成员的具体类型在编译器都能找到 还有人说dynamic变量是弱类型,但它也不是弱类型,他差不过是个 Dictionary<string, object>,是个字典,虽然字典的value是object,但里面的每个object都有自己的具体类型
Icedmilk 2016-03-11
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
你没有注意到实际上调用时用了许多“字符串”来标记,而不是真正的强类型编程吗? 弱类型的方式,就是这样的,初学者觉得动态编程爽,而初学者关心的是编程几秒钟的注意力,缺少质量意识。
匿名类背后是模板,是强类型
蓝色_冰点 2016-03-11
  • 打赏
  • 举报
回复

//当Class1在另一个程序集中时
namespace MyLib
{
    public class Class1
    {
        public string Method1(dynamic obj)
        {
           /* 这里将会发生异常:
“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的未经处理的异常在 System.Core.dll 中发生 

其他信息: “object”未包含“id”的定义
*/
            return obj.id;
        }
    }
}

using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            //Class2的Method1成功
            var c2 = new Class2();
            Console.Write(c2.Method1(new { id = "object2" }));

            //Class1的Method1失败
            var c = new MyLib.Class1();
            Console.Write(c.Method1(new { id = "object1" }));
        }
    }

    class Class2
    {
        public string Method1(dynamic obj)
        {
            return obj.id;
        }
    }
}
原来如此。
yangyi_2009 2016-03-11
  • 打赏
  • 举报
回复
引用 14 楼 sharp_ice 的回复:
[quote=引用 13 楼 yangyi_2009 的回复:]
[quote=引用 7 楼 sharp_ice 的回复:]
[quote=引用 4 楼 tcmakebest 的回复:]
跨程序集的 a.dll 中接收参数 p , 如果传入的是匿名类,这种用法其实就是传入了一个字典


引用 5 楼 caozhy 的回复:
反射可以。好比按理说你不能访问私有字段,但是反射一样可以。


如果确实可以,能否给段代码,简单点就行,注意条件是:跨程序集[/quote]

2楼的代码改一下就是跨程序集了。
// 程序集1 类Class1
public void Method1(object obj)
{
var idProperty = obj.GetType().GetProperties().FirstOrDefault(p => p.Name == "id");
if (idProperty != null)
{
var id = idProperty.GetValue(obj, null);
Debug.WriteLine(string.Format("id={0}", id));
}
}

// 程序集2
void Method2()
{
var cls1 = new Class1();
var obj = new { id = "object1" };
cls1.Method1(obj);
}
[/quote]

你的代码确实写得没错,但你确定你运行过上面的代码吗?[/quote]

蓝色_冰点 2016-03-11
  • 打赏
  • 举报
回复
引用 13 楼 yangyi_2009 的回复:
[quote=引用 7 楼 sharp_ice 的回复:] [quote=引用 4 楼 tcmakebest 的回复:] 跨程序集的 a.dll 中接收参数 p , 如果传入的是匿名类,这种用法其实就是传入了一个字典
引用 5 楼 caozhy 的回复:
反射可以。好比按理说你不能访问私有字段,但是反射一样可以。
如果确实可以,能否给段代码,简单点就行,注意条件是:跨程序集[/quote] 2楼的代码改一下就是跨程序集了。
// 程序集1 类Class1
public void Method1(object obj)
{
    var idProperty = obj.GetType().GetProperties().FirstOrDefault(p => p.Name == "id");
    if (idProperty != null)   
    {    
        var id = idProperty.GetValue(obj, null);
        Debug.WriteLine(string.Format("id={0}", id));     
    }
}

// 程序集2
void Method2()
{
    var cls1 = new Class1();
    var obj = new { id = "object1" };
    cls1.Method1(obj);
}
[/quote] 你的代码确实写得没错,但你确定你运行过上面的代码吗?
xuzuning 2016-03-11
  • 打赏
  • 举报
回复
这取决于目标方法的参数类型声明
Poopaye 2016-03-11
  • 打赏
  • 举报
回复
根本不会报错,楼主你逗我?
蓝色_冰点 2016-03-11
  • 打赏
  • 举报
回复
我X,真的可以, 但同样的代码,在另一个项目就是不行。回去找原因先
tcmakebest 2016-03-10
  • 打赏
  • 举报
回复
跨程序集的 a.dll 中接收参数 p , 如果传入的是匿名类,这种用法其实就是传入了一个字典
  • 打赏
  • 举报
回复
asp.net mvc 的这个写法是从别的平台、在10几年前玩儿剩的一个流行框架中抄来的写法,它没有使用面向接口的编程风格,主要是基于这个原因。 并不是说你自己设计、把握编程方向就应该也这样!
  • 打赏
  • 举报
回复
你没有注意到实际上调用时用了许多“字符串”来标记,而不是真正的强类型编程吗? 弱类型的方式,就是这样的,初学者觉得动态编程爽,而初学者关心的是编程几秒钟的注意力,缺少质量意识。
蓝色_冰点 2016-03-10
  • 打赏
  • 举报
回复
引用 4 楼 tcmakebest 的回复:
跨程序集的 a.dll 中接收参数 p , 如果传入的是匿名类,这种用法其实就是传入了一个字典
引用 5 楼 caozhy 的回复:
反射可以。好比按理说你不能访问私有字段,但是反射一样可以。
如果确实可以,能否给段代码,简单点就行,注意条件是:跨程序集
XBodhi. 2016-03-10
  • 打赏
  • 举报
回复
这个问题,我收了,回去帮你研究下,好像有点特殊性。你刚才一说匿名类给我弄蒙了。原来是那个 var
yangyi_2009 2016-03-10
  • 打赏
  • 举报
回复
引用 7 楼 sharp_ice 的回复:
[quote=引用 4 楼 tcmakebest 的回复:] 跨程序集的 a.dll 中接收参数 p , 如果传入的是匿名类,这种用法其实就是传入了一个字典
引用 5 楼 caozhy 的回复:
反射可以。好比按理说你不能访问私有字段,但是反射一样可以。
如果确实可以,能否给段代码,简单点就行,注意条件是:跨程序集[/quote] 2楼的代码改一下就是跨程序集了。
// 程序集1 类Class1
public void Method1(object obj)
{
    var idProperty = obj.GetType().GetProperties().FirstOrDefault(p => p.Name == "id");
    if (idProperty != null)   
    {    
        var id = idProperty.GetValue(obj, null);
        Debug.WriteLine(string.Format("id={0}", id));     
    }
}

// 程序集2
void Method2()
{
    var cls1 = new Class1();
    var obj = new { id = "object1" };
    cls1.Method1(obj);
}
为轮子而生 2016-03-10
  • 打赏
  • 举报
回复
如果MapRoute对构造函数中的参数进行了强类型约束,那么这种写法就是可行的,“相当于”使用了强类型,也可以理解为“省略”了类型名,并不是你理解的“匿名”。
秋的红果实 2016-03-10
  • 打赏
  • 举报
回复
常见情况,跨程序集需要using 命名空间;才能引用另一个程序集的方法 至于MVC中匿名方法,那是框架内部做了处理,和一般情况不同 早在visual basic 6.0时代,就有类似用法,例如:dim myvar,后面myvar=100.7,就自然识别为一个浮点型了,js里的var也是
threenewbee 2016-03-10
  • 打赏
  • 举报
回复
反射可以。好比按理说你不能访问私有字段,但是反射一样可以。
蓝色_冰点 2016-03-10
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
你没有注意到实际上调用时用了许多“字符串”来标记,而不是真正的强类型编程吗? 弱类型的方式,就是这样的,初学者觉得动态编程爽,而初学者关心的是编程几秒钟的注意力,缺少质量意识。
引用 9 楼 sp1234 的回复:
asp.net mvc 的这个写法是从别的平台、在10几年前玩儿剩的一个流行框架中抄来的写法,它没有使用面向接口的编程风格,主要是基于这个原因。 并不是说你自己设计、把握编程方向就应该也这样!
我现在要弄清楚的是匿名类的识别问题,不是什么设计方向之类的大话题
蓝色_冰点 2016-03-09
  • 打赏
  • 举报
回复
引用 2 楼 tcmakebest 的回复:
static void abc()
{
    var obj = new { a = 1, b = 2 };
    foreach (var m in obj.GetType().GetProperties())
    {
        Debug.WriteLine(string.Format("{0}={1}", m.Name, m.GetValue(obj, null)));
    }
}
你这代码当然没问题,我所说的一个关键条件是:跨程序集 跨程序集的时候,即便是反射也是获取不到另一个程序集的匿名类实例的字段的 但当我们使用MVC框架的时候,该框架定义的一些方法却能接收一个匿名类实例并能处理,这也是处于跨程序集的情况
加载更多回复(2)

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧