我有一个类,描述系统中的用户:
class userInfo
{
private SomeType1 p1;
private SomeType2 p2;
// ...
private SomeTypek pk;
}
将值设置为某些pi
涉及大量代码。
到目前为止,我为每个pi
定义了一个不同的方法,但是这个类增长了,所以我希望能够定义一个方法:
void SetPi(pi, SomeTypei value)
{
//Set pi's value to value
}
这种事情在C#中是否可行?
答案 0 :(得分:2)
通过这种方式设计与DB的交互并不是最好的选择。但如果你想:
public class Class
{
private string p1;
private int p2;
private decimal p3;
public void SetPi<T>(string name, T value)
{
var field = this.GetType().GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (field == null)
throw new ArgumentException("Field not found in Class.");
field.SetValue(this, value);
}
}
用法:
var c = new Class();
c.SetPi("p1", "AAA");
c.SetPi("p2", 12);
答案 1 :(得分:0)
如果它们的类型相同,我建议您将其作为列表公开。它们是不同类型意味着您可以在一种方法中执行此操作的唯一方法是更改为更通用的类型,例如object
或使用泛型T
。在这样做时,您将失去类型安全性并可能使方法复杂化。
您可能希望将字段更改为属性,为它们提供描述性名称(假设您实际上是这样的:p1,p2等没有意义,特别是如果它们是不同的类型;如果像p1那样, p2是有意义的,这意味着它应该是一个列表,名为p
或其他p
的缩写),并在内部调用一个方法来处理写入(代码更简单一些)使用CallerMemberName
)。
public string UserName
{
get
{
return _userName;
}
set
{
_userName = value;
WriteToDB(value);
}
}
// etc
private void WriteToDB(object value, [CallerMemberName] string propertyName = "")
{
// propertyName will be "UserName" when called above
}
// use like
myUser.UserName = "Tommy";
答案 2 :(得分:0)
我不知道这是否符合您的要求,即,使用字段是否至关重要,并且每种类型都有一个值(在这两种情况下,下面绝对不是答案),但这里是一种不涉及反射的东西,是强类型的:
class UserInfo
{
private static class Cache<T> where T : class
{
public static readonly ConditionalWeakTable<UserInfo, T> ValuesByInstance =
new ConditionalWeakTable<UserInfo, T>();
}
public void SetValue<T>(T value) where T : class
{
Cache<T>.ValuesByInstance.Remove(this);
Cache<T>.ValuesByInstance.Add(this, value);
}
public T GetValue<T>() where T : class
{
T value;
Cache<T>.ValuesByInstance.TryGetValue(this, out value);
return value;
}
}