我收到上述错误,无法解决.我google了一下,但无法摆脱它.
场景:
我有类BudgetAllocate,其属性是预算,是双重类型.
在我的dataAccessLayer中,
在我的一个课程中,我试图这样做:
double.TryParse(objReader[i].ToString(), out bd.Budget);
Run Code Online (Sandbox Code Playgroud)
这引发了这个错误:
在编译时,属性或索引器不能作为out或ref参数传递.
我甚至试过这个:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
Run Code Online (Sandbox Code Playgroud)
其他一切工作正常,层之间的引用存在.
给出以下方法:
public static void SetPropertyValue(object target, string propName, object value)
{
var propInfo = target.GetType().GetProperty(propName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
if (propInfo == null)
throw new ArgumentOutOfRangeException("propName", "Property not found on target");
else
propInfo.SetValue(target, value, null);
}
Run Code Online (Sandbox Code Playgroud)
如何编写它的表达式启用等效而无需为目标传递额外的参数?
为什么这样做而不是直接设置属性我可以听到你说.例如,假设我们有以下类,其属性具有公共getter但私有setter:
public class Customer
{
public string Title {get; private set;}
public string Name {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够致电:
var myCustomerInstance = new Customer();
SetPropertyValue<Customer>(cust => myCustomerInstance.Title, "Mr");
Run Code Online (Sandbox Code Playgroud)
现在这里是一些示例代码.
public static void SetPropertyValue<T>(Expression<Func<T, Object>> memberLamda , object value)
{
MemberExpression memberSelectorExpression; …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种方法将属性本身传递给一个函数.不是财产的价值.函数事先不知道哪个属性将用于排序.此示例中最简单的方法是:使用不同的参数类型创建4个覆盖.其他方式是使用typeof()内部功能.当Class1具有数百个属性时,这两种方式都是不可接受的.到目前为止我找到了以下方法:
class Class1
{
string vehName;
int maxSpeed;
int fuelCapacity;
bool isFlying;
}
class Processor
{
List<Class1> vehicles = null;
Processor(List<Class1> input)
{
vehicles = input;
}
List<Class1> sortBy(List<Class1> toSort, string propName)
{
if (toSort != null && toSort.Count > 0)
{
return toSort.OrderBy(x => typeof(Class1).GetProperty(propName).GetValue(x, null)).ToList();
}
else return null;
}
}
class OuterUser
{
List<Class1> vehicles = new List<Class1>();
// ... fill the list
Processor pr = new Processor(vehicles);
List<Class1> sorted = pr.sortBy("maxSpeed");
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这种方法,因为在将字符串传递给处理函数时存在"人为错误"的风险.当字符串由代码的其他部分生成时,这将变得更加丑陋.请提出更优雅的方法来实现Class1属性的传递以进行进一步处理.使用恕我直言的最佳选择(或类似的东西):
vehicles …Run Code Online (Sandbox Code Playgroud) 我可以将属性作为"out"或"ref"参数传递,如果不是,为什么不呢?
例如
Person p = new Person();
Run Code Online (Sandbox Code Playgroud)
...
public void Test(out p.Name);
Run Code Online (Sandbox Code Playgroud) 让我们假设我们有一个类如下所示:
public class Entity
{
public IList<string> SomeListOfValues { get; set; }
// Other code
}
Run Code Online (Sandbox Code Playgroud)
现在,假设我们想要使用EF Core Code First来保持这一点,并且我们正在使用像SQL Server这样的RDMBS.
一种可能的方法显然是创建一个Wraper包装字符串的包装类:
public class Wraper
{
public int Id { get; set; }
public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并重构类,以便它现在依赖于Wraper对象列表.在这种情况下,EF会生成一个表Entity,一个表,Wraper并建立一个"一对多"关系:对于每个实体,都有一堆包装器.
虽然这有效,但我不太喜欢这种方法,因为我们正在改变一个非常简单的模型,因为持久性问题.实际上,只考虑领域模型和代码,没有持久性,Wraper类在那里是毫无意义的.
有没有其他方法使用EF Core Code First将一个带有字符串列表的实体持久保存到RDBMS而不是创建一个包装类?当然,最后必须完成同样的事情:必须创建另一个表来保存字符串,并且必须建立"一对多"关系.我只想用EF Core做这个,而不需要在域模型中编写包装类.
考虑这些属性,
double _temperature;
public double Temperature
{
get { return _temperature; }
set { _temperature = value; }
}
double _humidity;
public double Humidity
{
get { return _humidity; }
set { _humidity = value; }
}
bool _isRaining;
public bool IsRaining
{
get { return _isRaining; }
set { _isRaining = value; }
}
Run Code Online (Sandbox Code Playgroud)
现在我想制作一个像这样的列表/集合/容器,
PropertyContainer.Add(Temperature); //Line1
PropertyContainer.Add(Humidity); //Line2
PropertyContainer.Add(IsRaining); //Line3
Run Code Online (Sandbox Code Playgroud)
我想这样做,以后我可能能够使用索引访问属性的当前值,像这样,
object currentTemperature = PropertyContainer[0];
object currentHumidity = PropertyContainer[1];
object currentIsRaining = PropertyContainer[2];
Run Code Online (Sandbox Code Playgroud)
但显然,这不会起作用,因为 …
假设你有这样的课程
public class Foo
{
public int Bar { get; set; } = 42;
}
Run Code Online (Sandbox Code Playgroud)
如果您尝试将该属性作为ref参数传递,则编译器会发出错误
CS0206属性或索引器不能作为out或ref参数传递
因为在实践中在上面的例子中财产被编译成这是可以理解get_Bar()和set_Bar()方法.但是如果你在属性上使用增量运算符,比如
var foo = new Foo();
foo.Bar++;
Run Code Online (Sandbox Code Playgroud)
它按预期工作.为此,编译器需要生成类似这样的伪代码:
var foo = new Foo();
int tmp = foo.get_Bar();
tmp++;
foo.set_Bar(tmp);
Run Code Online (Sandbox Code Playgroud)
所以理论上编译器可以做类似的事情ref:
var foo = new Foo();
int tmp = foo.get_Bar();
DoSomething(ref tmp);
foo.set_Bar(tmp);
Run Code Online (Sandbox Code Playgroud)
有没有技术上的原因,编译器不这样做,或者这只是C#团队的设计决定?
基本的基础我搞砸了C#属性和引用类型.
public Address adr { get; set; }
public class Address
{
//Field
public string AddressLine1;
//Property
public string Country {get; set;}
}
public void ChangeCountry(string _Country)
{
_Country = "US";
}
public void ChangeAddress(Address _adr)
{
_adr.Country = "US";
}
private void button1_Click(object sender, EventArgs e)
{
adr = new Address();
ChangeCountry(adr.Country);
MessageBox.Show(adr.Country);
//(?)Country is reported empty string. Property did not updated outside.
ChangeAddress(adr);
MessageBox.Show(adr.Country);
//OK. Country is reported 'US'
}
Run Code Online (Sandbox Code Playgroud)
在这里我的问题;
当我们将一个Property(简单或复杂的)直接传递给将尝试修改它的方法时,是否确保此属性在任何地方都被修改?我的意思是像ref关键字一样?因为我不能将"ref"关键字与属性一起使用;我直接将属性传递给方法进行修改,我不确定它是否总是会在外部更新/修改.当我没有看到ref关键字; 这让我很担心:)
在上面的例子中; …
c# ×8
properties ×4
.net ×1
.net-core ×1
arguments ×1
containers ×1
expression ×1
indexer ×1
linq ×1
list ×1
ref ×1
reference ×1