如何公开方法以在大型类中设置成员

本文关键字:设置 成员 大型 何公开 方法 | 更新日期: 2023-09-27 18:31:47

我有一个类,描述系统中的用户:

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# 中可能吗?

如何公开方法以在大型类中设置成员

以这种方式设计与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);

如果它们都是相同的类型,我建议您将其公开为列表。它们是不同的类型意味着您可以在一种方法中执行此操作的唯一方法是更改为更通用的类型,例如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";
我不知道

这是否满足您的要求,即使用字段是否至关重要,并且每种类型都有一个值(在这两种情况下,下面绝对不是答案),但这里有一些不涉及反射并且是强类型的:

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;
    }
}