我听谈话约C#4的dynamic关键词,我想知道......请问这个功能是正交的其它.NET功能,例如将它支持扩展方法?
public static class StrExtension {
public static string twice(this string str) { return str + str; }
}
...
dynamic x = "Yo";
x.twice(); // will this work?
Run Code Online (Sandbox Code Playgroud)
注意:这个问题是在C#4发布之前提出的,这就是为什么它将在未来时使用.
'System.Data.SqlClient.SqlConnection'没有名为'Query'的适用方法,但似乎有一个名称的扩展方法.无法动态分派扩展方法.考虑转换动态参数或调用扩展方法而不使用扩展方法语法.
现在,我知道如何解决这个问题,但我正在努力更好地理解错误本身.我正在上课,以利用Dapper.最后,我将提供一些更多自定义功能,以使我们的数据访问类型更加简化.特别是在追踪和东西建设.但是,现在它就像这样简单:
public class Connection : IDisposable
{
private SqlConnection _connection;
public Connection()
{
var connectionString = Convert.ToString(ConfigurationManager.ConnectionStrings["ConnectionString"]);
_connection = new SqlConnection(connectionString);
_connection.Open();
}
public void Dispose()
{
_connection.Close();
_connection.Dispose();
}
public IEnumerable<dynamic> Query(string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
// this one works fine, without compile error, so I understand how to
// workaround the error
return Dapper.SqlMapper.Query(_connection, sql, param, transaction, buffered, …Run Code Online (Sandbox Code Playgroud) 我正在读Jon Skeet的书"C#in Depth,2nd Edition".他说我们可以使用动态参数调用扩展方法,使用两种解决方法,就像
dynamic size = 5;
var numbers = Enumerable.Range(10, 10);
var error = numbers.Take(size);
var workaround1 = numbers.Take((int) size);
var workaround2 = Enumerable.Take(numbers, size);
Run Code Online (Sandbox Code Playgroud)
然后他说"如果你想用动态值作为隐含this值调用扩展方法,两种方法都会有效".我不知道如何实现它.
非常感谢.
给出以下字符串扩展方法
namespace JHS.ExtensionMethods
{
public static class StringExtensions
{
public static string ToUSAPhone(this String str)
{
return String.Format("{0:(###) ###-####}", Double.Parse(str));
}
}
}
Run Code Online (Sandbox Code Playgroud)
@using语句被添加到MVC4 Razor视图中
@using JHS.ExtensionMethods;
Run Code Online (Sandbox Code Playgroud)
以下字符串值调用扩展方法
@Model.producer.phone.ToUSAPhone()
Run Code Online (Sandbox Code Playgroud)
这会导致以下错误
'string' does not contain a definition for 'ToUSAPhone'
Run Code Online (Sandbox Code Playgroud)
我还尝试将命名空间放在/ Views文件夹的web.config中并收到相同的错误.
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization"/>
<add namespace="System.Web.Routing" />
<add namespace="JHS.ExtensionMethods"/>
</namespaces>
</pages>
Run Code Online (Sandbox Code Playgroud)
我通过在C#类中调用相同的调用来验证扩展方法的工作原理
string test=producer.phone.ToUSAPhone();
Run Code Online (Sandbox Code Playgroud)
看来扩展方法的引用在MVC4 Razor视图中不可用,但我无法弄清楚为什么?
灵感来自这个问题.
简短版本:M(dynamic arg)如果只有一个重载M或所有重载M具有相同的返回类型,为什么编译器不能找出编译时类型?
根据规范,§7.6.5:
如果至少满足下列条件之一,则动态绑定调用表达式(第7.2.2节):
primary-expression具有编译时类型dynamic.
可选参数列表的至少一个参数具有编译时类型dynamic,而primary-expression没有委托类型.
这是有道理的
class Foo {
public int M(string s) { return 0; }
public string M(int s) { return String.Empty; }
}
Run Code Online (Sandbox Code Playgroud)
编译器无法弄清楚编译时的类型
dynamic d = // dynamic
var x = new Foo().M(d);
Run Code Online (Sandbox Code Playgroud)
因为直到运行时才会知道M调用了哪个重载.
但是,为什么编译器无法计算编译时类型,如果M只有一个重载或所有重载M返回相同的类型?
我想了解为什么规范不允许编译器在编译时静态地键入这些表达式.
我有follow方法返回一个表示IEnumerable<'a>('a =匿名类型)的动态对象:
public dynamic GetReportFilesbyStoreProductID(int StoreProductID)
{
Report report = this.repository.GetReportByStoreProductID(StoreProductID);
if (report == null || report.ReportFiles == null)
{
return null;
}
var query = from x in report.ReportFiles
orderby x.DisplayOrder
select new { ID = x.RptFileID, Description = x.LinkDescription, File = x.LinkPath, GroupDescription = x.ReportFileGroup.Description };
return query;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够访问Count此IEnumerable匿名类型的属性.我正在尝试使用以下代码访问上述方法,但它失败了:
dynamic Segments = Top20Controller.GetReportFilesbyStoreProductID(StoreProductID");
if (Segments.Count == 0) // <== Fails because object doesn't contain count.
{
...
}
Run Code Online (Sandbox Code Playgroud)
dynamic关键字如何运作?我很好奇,看看是否有其他人遇到过同样的问题......我正在ORM上使用Dapper作为项目,并且正在创建一些我自己的扩展方法,IDbConnection以简化代码,我遇到了(我发现的是)令人费解的错误.
我将介绍我经历的过程.
首先,我在一个名为DbExtensionsso 的静态类中为我的项目添加了一个扩展方法:
using System.Collections.Generic;
using System.Data;
using System.Linq;
public static class DbExtensions
{
public static T Scalar<T>(
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
var ret = cnn.Query<T>(sql, param as object, transaction, buffered, commandTimeout, commandType).First();
return ret;
}
}
Run Code Online (Sandbox Code Playgroud)
这会使用以下描述创建编译错误:
'System.Data.IDbConnection' has no applicable method named 'Query' but appears to have an extension method by …
在今天遇到Massive的一些问题后,我决定创建一个简单的测试程序来说明问题.我想知道,我在这段代码中犯的错误是什么:
var list = new List<string>
{
"Hey"
};
dynamic data = list.Select(x => x);
var count = data.Count();
Run Code Online (Sandbox Code Playgroud)
最后一行抛出错误:'object'不包含'Count'的定义
为什么"数据"被视为对象?出现此问题是因为我正在调用扩展方法吗?
以下代码有效:
var list = new List<string>
{
"Hey"
};
dynamic data = list.Select(x => x);
foreach (var s in data)
{
}
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下"数据"被正确地视为IEnumerable?
我有一个泛型方法,通过将一个操作数强制转换来调用运算符dynamic.有两种不同的电话:
//array is T[][]
//T is MyClass
array[row][column] != default(T) as dynamic
Run Code Online (Sandbox Code Playgroud)
这是工作和调用static bool operator !=(MyClass a, MyClass b)(即使双方都是null).
让我感到惊讶的是以下行的行为:
//array, a and b are T[][]
//T is MyClass
array[row][column] += a[line][i] * (b[i][column] as dynamic);
Run Code Online (Sandbox Code Playgroud)
这个电话
public static MyClass operator *(MyClass a, object b)和
public static MyClass operator +(MyClass a, object b)
而不是
public static MyClass operator *(MyClass a, MyClass b)和
public static MyClass operator +(MyClass a, MyClass b).
删除 …
我正在尝试找到一个好的,干净的设计模式或普遍接受的实现来处理类型的枚举,其中仅在运行时知道单个类型.
我之前已经问过类似的问题,但我仍然不清楚替代实现相比交换机或一系列if-thens有明显的优势.
首先,我将演示一些实现,然后我将问一个问题: 这些实现是否比简单的交换机更好或更优先?如果是这样,为什么?如果没有,为什么不呢?
在我的应用程序中,我通过流发送和接收数据.在运行时,我通过序列化接收数据结构,该结构描述了我的二进制数据中的字段.这包括字段中的数据类型,即Int32,Bool,Double等.在设计时,我所知道的是数据可能是几种类型中的一种.我需要从流中读取字段并适当地处理数据.
如果允许启用类型,则解决方案可能如下:
非工作代码:
object ReadDataField(byte [] buff, ref int position,
Dictionary<int, Type> fields)
{
object value;
int field = buff[position];
position++;
switch(fields[field])
{
case typeof(Int32):
{
value = (Int32)BitConverter.ToInt32(buff, position);
position += sizeof(Int32);
break;
}
case typeof(Int16):
{
value = (Int16)BitConverter.ToInt16(buff, position);
position += sizeof(Int16);
break;
}
// Etc...
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这段代码的优点是简单易读,易于维护.
但是,由于在C#中没有打开类型,我实现了以下内容:
工作守则:
enum RawDataTypes
{
Int32,
Int16,
Double,
Single,
etc.
}
object ReadDataField(byte [] buff, ref int position,
Dictionary<int, RawDataTypes> …Run Code Online (Sandbox Code Playgroud) c# ×10
dynamic ×7
c#-4.0 ×2
dapper ×2
.net ×1
.net-4.5 ×1
asp.net ×1
asp.net-mvc ×1
generics ×1
polymorphism ×1
razor ×1
reflection ×1