如何简化下面的代码以避免在泛型方法上传递类型推断的对象?
using System;
using System.Linq.Expressions;
namespace lambda
{
class Program
{
static void Main(string[] args)
{
var area = new Area { Name = "New Area" };
var propertyName = area.GetPropertyName(area, a => a.Name); // propertyName is COMPILE time checked
Console.WriteLine(propertyName);
}
}
public class Area
{
public int Id;
public string Name { get; set; }
}
public static class Extension
{
public static string GetPropertyName<T>(this Area entity, T e, Expression<Func<T, object>> path) // T e for type inference
{
var member = path.Body as MemberExpression;
if (member == null) throw new ArgumentException();
return member.Member.Name;
}
}
}
我的意思是代替使用area.GetPropertyName(area,a =&gt; a.Name)调用扩展方法 只是像这个区域一样调用.GetPropertyName(a =&gt; a.Name),避免仅为类型推断传递区域对象
我想除非我将方法的签名重构为GetPropertyName(此IEntity实体,Expression&gt; path),否则我无法做到 但是在那种情况下,我希望在编写代码时不太想要,因为我需要在每次调用时指定类型 我的意思是area.GetPropertyName(a =&gt; a.Name)似乎对我来说不像编写区域那么清晰.GetPropertyName(area,a =&gt; a.Name)
答案 0 :(得分:0)
下面的示例代码适用于要求的要求,在调用扩展方法时无需传递对象本身以进行类型推断 我使用了一个基类和一个接口,对于我的所有域类都可以正常工作。 见下面的代码
namespace UnitTestProject
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq.Expressions;
public interface IEntity<T>
{
}
public abstract class Entity<T> : IEntity<T> where T : class
{
}
public class Area : Entity<Area>
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public bool Closed { get; set; }
public string Description { get; set; }
}
public static class EntityExtension
{
public static string GetPropertyName<T>(this IEntity<T> entity, Expression<Func<T, object>> expr) // T e for type inference
{
var unary = expr.Body as UnaryExpression;
var member = expr.Body as MemberExpression;
return member != null ? member.Member.Name : (unary != null ? ((MemberExpression)unary.Operand).Member.Name : String.Empty);
}
}
[TestClass]
public class UnitTest
{
[TestMethod]
public void GetPropertyName_Tests()
{
var area = new Area();
var x = area.GetPropertyName(a => a.Id);
var y = area.GetPropertyName(a => a.Name);
var v = area.GetPropertyName(a => a.Created);
var w = area.GetPropertyName(a => a.Closed);
var z = area.GetPropertyName(a => a.Description);
Assert.AreEqual(x, "Id");
Assert.AreEqual(y, "Name");
Assert.AreEqual(v, "Created");
Assert.AreEqual(w, "Closed");
Assert.AreEqual(z, "Description");
}
}
}