如何创建C#泛型方法

如何创建C#泛型方法,c#,generics,C#,Generics,我有一个复制粘贴到许多类的方法。该方法将模型分解为IdNameViewModel。如何使用此方法创建一个类,以便传入存储库模型并获取该模型的IDName列表 注意:ProjectValue是我传入的一个模型/类,但它实际上可以是任何包含id和name属性的模型/类 private IdNameVM HydrateEntityToVM(ProjectValue projectValue) { if (projectValue == null) return null; retur

我有一个复制粘贴到许多类的方法。该方法将模型分解为IdNameViewModel。如何使用此方法创建一个类,以便传入存储库模型并获取该模型的IDName列表

注意:ProjectValue是我传入的一个模型/类,但它实际上可以是任何包含id和name属性的模型/类

private IdNameVM HydrateEntityToVM(ProjectValue projectValue)
{
    if (projectValue == null) return null;

    return new IdNameVM()
    {
        Id = projectValue.Id,
        Name = projectValue.Name
    };
}
以下是我根据以下答案得出的结论:

public class GenericHydrateIdName<TModel> where TModel : INameId
    {
        public IdNameVM HydrateEntityToVM(TModel model)
        {
            if (model == null) return null;

            return new IdNameVM()
            {
                Id = model.Id,
                Name = model.Name
            };
        }
    }
}
public类GenericHydrateIdName,其中TModel:INameId
{
公共IdNameVM和EntityToVM(TModel模型)
{
if(model==null)返回null;
返回新的IdNameVM()
{
Id=model.Id,
Name=model.Name
};
}
}
}
请注意,如果有人遵循,上面的类会导致太多的工作,并且违反了干净代码原则。我使用了下面的扩展方法。

这些是C#的基础。看看这个

class MyClass,其中T:ProjectValue
{
私有IdNameVM和EntityToVM(T项目值)
{
if(projectValue==null)返回null;
返回新的IdNameVM()
{
Id=projectValue.Id,
Name=projectValue.Name
};
}
}
如果您不知道模型的抽象(但请小心,此方法可以使用任何包含id和name公共属性的对象),请尝试以下操作:

public void SomeGenericMethod<T>(T model) where T : class
{
    if (model == null) return null;

    var propId = model.GetType().GetProperty("id");
    var propName = model.GetType().GetProperty("name");
    if (propId == null || propName == null)
        return;


    return new IdNameVM()
    {
        Id = model.Id,
        Name = model.Name
    };
}
public void SomeGenericMethod(T model),其中T:class
{
if(model==null)返回null;
var propId=model.GetType().GetProperty(“id”);
var propName=model.GetType().GetProperty(“名称”);
如果(propId==null | | propName==null)
返回;
返回新的IdNameVM()
{
Id=model.Id,
Name=model.Name
};
}
这些是C#的基础知识。看看这个

class MyClass,其中T:ProjectValue
{
私有IdNameVM和EntityToVM(T项目值)
{
if(projectValue==null)返回null;
返回新的IdNameVM()
{
Id=projectValue.Id,
Name=projectValue.Name
};
}
}
如果您不知道模型的抽象(但请小心,此方法可以使用任何包含id和name公共属性的对象),请尝试以下操作:

public void SomeGenericMethod<T>(T model) where T : class
{
    if (model == null) return null;

    var propId = model.GetType().GetProperty("id");
    var propName = model.GetType().GetProperty("name");
    if (propId == null || propName == null)
        return;


    return new IdNameVM()
    {
        Id = model.Id,
        Name = model.Name
    };
}
public void SomeGenericMethod(T model),其中T:class
{
if(model==null)返回null;
var propId=model.GetType().GetProperty(“id”);
var propName=model.GetType().GetProperty(“名称”);
如果(propId==null | | propName==null)
返回;
返回新的IdNameVM()
{
Id=model.Id,
Name=model.Name
};
}

要创建泛型方法,必须记住以下几条规则

  • 您将支持哪些类型
  • 结果会怎样
  • 解之间一定有奇点
  • 让我们以上面提到的例子为例:您需要一个名为
    HydrateEntityToVM
    的通用方法。第一步是方法的声明语法以及从强类型的T类型转换对象

    这里需要注意的一点是,您正在传递一个T类型,并且希望结果始终是IdNameVM类,那么您的实现应该如下所示:

    //The Method declaration of T type
    private IdNameVM  HydrateEntityToVM<T>(T projectValue)
    {
         //Checking whether the object exists or not
         //if null than return the default value of IdNameVM
         if(projectValue == null) return default(IdNameVM);  
    
         //Checking if we are supporting the implementation or not for that class
         //In your case YourStrongTypeClass is ProjectValue Class
         if(projectValue is YourStrongTypeClass) 
         {
    
             //Casting the T object to strong type object
             var obj = projectValue as YourStrongTypeClass;
    
             return new IdNameVM()
             {
                Id = obj.Id,
                Name = obj.Name
             };
         } 
         else
         {
            //The else statement is for if you want to handle some other type of T implementation
            throw new NotImplementedException($"The type {typeof(T)} is not implemented");
         }
    }
    
    //T类型的方法声明
    私有IdNameVM和EntityToVM(T项目值)
    {
    //检查对象是否存在
    //如果为null,则返回IdNameVM的默认值
    if(projectValue==null)返回默认值(IdNameVM);
    //检查我们是否支持该类的实现
    //在您的例子中,您的StrongTypeClass是ProjectValue类
    if(projectValue是您的strongtypeclass)
    {
    //将T对象强制转换为强类型对象
    var obj=项目值,作为您的strong类型类;
    返回新的IdNameVM()
    {
    Id=对象Id,
    Name=obj.Name
    };
    } 
    其他的
    {
    //else语句用于处理其他类型的T实现
    抛出新的NotImplementedException($“类型{typeof(T)}未实现”);
    }
    }
    
    要创建泛型方法,必须记住以下几条规则

  • 您将支持哪些类型
  • 结果会怎样
  • 解之间一定有奇点
  • 让我们以上面提到的例子为例:您需要一个名为
    HydrateEntityToVM
    的通用方法。第一步是方法的声明语法以及从强类型的T类型转换对象

    这里需要注意的一点是,您正在传递一个T类型,并且希望结果始终是IdNameVM类,那么您的实现应该如下所示:

    //The Method declaration of T type
    private IdNameVM  HydrateEntityToVM<T>(T projectValue)
    {
         //Checking whether the object exists or not
         //if null than return the default value of IdNameVM
         if(projectValue == null) return default(IdNameVM);  
    
         //Checking if we are supporting the implementation or not for that class
         //In your case YourStrongTypeClass is ProjectValue Class
         if(projectValue is YourStrongTypeClass) 
         {
    
             //Casting the T object to strong type object
             var obj = projectValue as YourStrongTypeClass;
    
             return new IdNameVM()
             {
                Id = obj.Id,
                Name = obj.Name
             };
         } 
         else
         {
            //The else statement is for if you want to handle some other type of T implementation
            throw new NotImplementedException($"The type {typeof(T)} is not implemented");
         }
    }
    
    //T类型的方法声明
    私有IdNameVM和EntityToVM(T项目值)
    {
    //检查对象是否存在
    //如果为null,则返回IdNameVM的默认值
    if(projectValue==null)返回默认值(IdNameVM);
    //检查我们是否支持该类的实现
    //在您的例子中,您的StrongTypeClass是ProjectValue类
    if(projectValue是您的strongtypeclass)
    {
    //将T对象强制转换为强类型对象
    var obj=项目值,作为您的strong类型类;
    返回新的IdNameVM()
    {
    Id=对象Id,
    Name=obj.Name
    };
    } 
    其他的
    {
    //else语句用于处理其他类型的T实现
    抛出新的NotImplementedException($“类型{typeof(T)}未实现”);
    }
    }
    
    基本上,我能看到的最好的类型安全方式是有一个接口

    interface INameId
    {
        int Id { get; set; }
        string Name { get; set; }
    }
    
    您可以在每个类中使用此接口。根据您当前的使用情况,我建议使用扩展功能

    static class VMExtensions
    {
    
        public static IdNameVM HydrateEntityToVM<TModel>(this TModel model)
            where TModel : INameId
        {
            if (model == null) return null;
    
            return new IdNameVM()
            {
                Id = model.Id,
                Name = model.Name
            };
        }
    
        // update: without generics as Marcus Höglund pointed out
        public static IdNameVM HydrateEntityToVM2(this INameId model)
        {
            if (model == null) return null;
    
            return new IdNameVM()
            {
                Id = model.Id,
                Name = model.Name
            };
        }
    
        static void Test()
        {
            var model = new ProjectValue();
            var model2 = new AnotherModel();
    
            var viewModel = model2.HydrateEntityToVM();
            var viewModel2 = model2.HydrateEntityToVM();
    
        }
    
    }
    
    静态类扩展
    {
    公共静电