【问题标题】:c# dynamic type correct usagec#动态类型正确用法
【发布时间】:2021-05-02 14:32:15
【问题描述】:

我有 2 个类共享一些属性

public class SportsUser
{
    public string errorCode { get; set; }
    //the sportsuser and SportsAdminUser is from a different database hence the long and int difference
    public long userId { get; set; }      
    ...        
}

public class SportsAdminUser
{
    public int userId { get; set; }
    public string errorCode { get; set; }
    ...
}

我还有一个 web api 调用,可以通过 sessiontoken 或用户名和密码来确定我需要实例化上面的哪个类。

...
UserHandler userHandler = new UserHandler();                    
string errorCode = "";
int adminId = 0;
if (!string.IsNullOrEmpty(sessionToken))
{
      SportsUser sportsUser = new SportsUser();
      sportsUser = userHandler.CheckUpdateUserSessionToken(sessionToken);
      adminId = Convert.ToInt32(sportsUser.userId);
      errorCode = sportsUser.errorCode;
}
else
{
      SportsAdminUser sportsAdminUser = new sportsAdminUser();
      sportsAdminUser = userHandler.LoginUser(username, password);
      adminId = sportsAdminUser.userId;
      errorCode = sportsAdminUser.errorCode;
}

if (errorCode != "SESSION_INVALID" && errorCode != "INVALID_CREDENTIALS" && errorCode != "ACCOUNT_LOCKED")
{
Tuple<int, List<PunterTransaction>> resultTupe = businessLogic.GetCustomerTransactions(customerId, transactionsFromDateTimeTicks, transactionsToDateTimeTicks, adminId);
...
                    

为了使这个更清洁,我尝试使用如下动态,但 userid 属性是 long vs int,具体取决于使用的类。我该如何解决这个问题以及在这种情况下使用动态是否正确?谢谢。

UserHandler userHandler = new UserHandler();
dynamic tmp = new System.Dynamic.ExpandoObject();
if (!string.IsNullOrEmpty(sessionToken))
{
     tmp = userHandler.CheckUpdateUserSessionToken(sessionToken);
}
else
{
     tmp = userHandler.LoginUser(username, password);
}

if (tmp.errorCode != "SESSION_INVALID" && tmp.errorCode != "INVALID_CREDENTIALS" && tmp.errorCode != "ACCOUNT_LOCKED")
{
    Tuple<int, List<CustomerTransaction>> resultTupe = businessLogic.GetCustomerTransactions(customerId, transactionsFromDateTimeTicks, transactionsToDateTimeTicks, tmp.bookmakerId);
                    

【问题讨论】:

  • 也许我没有正确理解这种情况,但它不能只是一个返回具有约束“struct”的泛型类型的方法?
  • 可以使用泛型吗?你能向我解释一下它是如何工作的吗?
  • 其实很抱歉。我误解了你。您的意思是函数 loginuser 和 checkupdateUserSessionToken 只能在结构中返回错误代码和用户 ID?这是不可能的,因为在某些情况下,我实际上需要从 sportsuser 和 sportsadminuser 对象访问其他属性。所以在其他地方使用这两个函数。
  • 只有id属性类型不同?其他都一样吗?
  • 不,sportsuser 和sportsadminuser 完全不同。他们共享的唯一道具是错误代码和用户 ID(尽管类型是 int 与 long)。

标签: c# .net dynamic


【解决方案1】:

昨天我没有正确理解这一点。我需要澄清一些事情,在初始化 tmp 变量后你想要实现什么。您想传递 int 或 long 还是动态? 我无法理解这种情况,但是如果您想使用动态,我建议您像这样实现它。

我放了一些cmets来更好地理解。

创建抽象类

public abstract class User
{
    public string ErrorCode { get; set; }
    public dynamic UserId { get; set; }
}

SportsUserSportsAdminUser 类将继承 User

public class SportsUser : User
{
}


public class SportsAdminUser : User 
{
}

用法:

UserHandler userHandler = new UserHandler();
string sessionToken = "something";
string username = "user";
string password = "password";
User tmp;

if (!string.IsNullOrEmpty(sessionToken))
{
    tmp = userHandler.CheckUpdateUserSessionToken("sessionToken");
}
else
{
    tmp = userHandler.LoginUser(username, password);
}

//For testing type
var sportsUserTestType = userHandler.CheckUpdateUserSessionToken("sessionToken").UserId.GetType(); //int
var sportsAdminUserTestType = userHandler.LoginUser(username, password).UserId.GetType(); // long

if (tmp.ErrorCode != "SESSION_INVALID" && tmp.ErrorCode != "INVALID_CREDENTIALS" &&
            tmp.ErrorCode != "ACCOUNT_LOCKED")
 {
      Tuple<int, List<string>> resultTupe = businessLogic.GetCustomerTransactions(customerId, transactionsFromDateTimeTicks, transactionsToDateTimeTicks, tmp.UserId);

 }

我对 UserHandler 的模拟

public class UserHandler
{
    public SportsUser CheckUpdateUserSessionToken(string sessionToken)
    {
        //Do something

        return new SportsUser()
        {
            ErrorCode= "error1",
             UserId = 1 //int
        };
    }

    public SportsAdminUser LoginUser(string username, string password)
    {
        //Do something
        return new SportsAdminUser()
        {
            ErrorCode = "error2",
            UserId = 2L // long
        };
    }
}

注意GetCustomerTransactions 方法仍然需要处理动态类型(最后一个参数)

希望有帮助

【讨论】:

    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多