如何在 C# 中使用 T 类型进行类型转换并访问其 属性 和变量
How to typecast in c# with T type and access its property and variables
IDE:C#.net,Winforms
在我开始之前请看一下情况:
public class ParentClass
{
}
public class A : ParentClass
{
public int A_item1;
public string A_item2;
public int CommonVariable;
}
public class B : ParentClass
{
public int B_item1;
public string B_item2;
public int CommonVariable;
}
现在我有 form1.cs 从我使用它的地方
private void button1_Click(object sender, EventArgs e)
{
List<ParentClass> lstA = new List<ParentClass>();
lstA.Add(new A());
lstA.Add(new A());
List<ParentClass> lstB = new List<ParentClass>();
lstA.Add(new B());
lstA.Add(new B());
lstA = AssignValue<A>(lstA);
lstB = AssignValue<B>(lstB);
}
private List<ParentClass> AssignValue<T>(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
{
(item as T).CommonProperty = 5; // can you tell me how to dynamically type cast here, what ever type is supplied it will type cast accordingly..
}
return lstParent;
}
如您所见,我创建了 2 个子 classes A、B 和一个 ParentClass,
在 form1.cs 中,我创建了 2 个类型为 Parentclass 的列表,并在列表 1 中添加类型对象,在列表 2 中添加 B 类型对象,并将其传递给函数 AssignValues
在这里我想自动键入种姓,无论用户提供类型 T,你能告诉我如何实现这一点。
请不要建议我在父类中移动这个变量,因为在我的项目中我不能修改父类class,我也不想用switch case来解决这个问题。
我还是很困惑,但是我在例子中得到的,你可以像这样使用动态(C#4.0)-
private List<ParentClass> AssignValue<T>(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
{
dynamic objData = Convert.ChangeType(item, typeof(T));
if (objData != null)
{
//This call would throw exception if CommonProperty is not member of the T Class
objData.CommonProperty = 5;
}
}
return lstParent;
}
如果这不是您想要的情况,请详细说明您面临的问题是什么
创建新界面:
public interface IHasCommonProperty
{
int CommonProperty {get; set;}
}
public class A : ParentClass, IHasCommonProperty
{
public int A_item1;
public string A_item2;
public int CommonProperty {get ; set; }
}
public class B : ParentClass, IHasCommonProperty
{
public int B_item1;
public string B_item2;
public int CommonProperty {get ; set; }
}
private List<ParentClass> AssignValue(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
{
var commonInterface = item as IHasCommonProperty;
if (commonInterface != null)
commonInterface.CommonProperty = 5;
}
return lstParent;
}
您需要做的是让编译器知道您的 classes 是如何布局的。
基本上你必须告诉它,"this T
type, here's what I know about it"。
由于两者之间没有任何共同点,除了两个属性具有相同的名称和类型之外,编译器不会让您轻易地做到这一点。请注意,具有相同名称和类型但属于不同类型的两个属性是不同的属性,您可以将其强制转换为允许您访问它们的通用属性。
除了 dynamic
之外,这里已经有另一个答案,但让我们找到一个更好的方法。
你要做的就是将公共 属性 向下移动到你的公共基础 class:
public class ParentClass
{
public int CommonVariable;
}
public class A : ParentClass
{
public int A_item1;
public string A_item2;
}
public class B : ParentClass
{
public int B_item1;
public string B_item2;
}
然后你必须告诉泛型方法,它将作为 T
给出的所有类型至少是公共基础 class:
private List<ParentClass> AssignValue<T>(List<ParentClass> lstParent)
where T : ParentClass
看到我上面加的那个where T : ParentClass
子句,这告诉编译器每个类型都是那个类型,现在代码可以这样写:
{
foreach (var item in lstParent)
item.CommonVariable = 5;
return lstParent;
}
现在,说了这么多我质疑这个方法的有效性。
就目前而言,您实际上不需要它是通用的。如果将公共域下移到基class,你可以这样写方法:
private List<ParentClass> AssignValue(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
item.CommonVariable = 5;
return lstParent;
}
如果您不能或不愿将公共字段向下移动到基中class,您可以使用另一种方式,使用接口。
首先将字段变成 属性,然后声明一个接口公开此 属性 并在每个 class 上实现 属性,然后让方法,仍然不必是通用的,采用该接口:
public class ParentClass
{
}
public interface ICommon
{
int CommonVariable { get; set; }
}
public class A : ParentClass : ICommon
{
public int A_item1;
public string A_item2;
public int CommonVariable { get; set; }
}
public class B : ParentClass : ICommon
{
public int B_item1;
public string B_item2;
public int CommonVariable { get; set; }
}
private List<ICommon> AssignValue(List<ICommon> lstParent)
{
foreach (var item in lstParent)
item.CommonVariable = 5;
return lstParent;
}
IDE:C#.net,Winforms
在我开始之前请看一下情况:
public class ParentClass
{
}
public class A : ParentClass
{
public int A_item1;
public string A_item2;
public int CommonVariable;
}
public class B : ParentClass
{
public int B_item1;
public string B_item2;
public int CommonVariable;
}
现在我有 form1.cs 从我使用它的地方
private void button1_Click(object sender, EventArgs e)
{
List<ParentClass> lstA = new List<ParentClass>();
lstA.Add(new A());
lstA.Add(new A());
List<ParentClass> lstB = new List<ParentClass>();
lstA.Add(new B());
lstA.Add(new B());
lstA = AssignValue<A>(lstA);
lstB = AssignValue<B>(lstB);
}
private List<ParentClass> AssignValue<T>(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
{
(item as T).CommonProperty = 5; // can you tell me how to dynamically type cast here, what ever type is supplied it will type cast accordingly..
}
return lstParent;
}
如您所见,我创建了 2 个子 classes A、B 和一个 ParentClass,
在 form1.cs 中,我创建了 2 个类型为 Parentclass 的列表,并在列表 1 中添加类型对象,在列表 2 中添加 B 类型对象,并将其传递给函数 AssignValues
在这里我想自动键入种姓,无论用户提供类型 T,你能告诉我如何实现这一点。
请不要建议我在父类中移动这个变量,因为在我的项目中我不能修改父类class,我也不想用switch case来解决这个问题。
我还是很困惑,但是我在例子中得到的,你可以像这样使用动态(C#4.0)-
private List<ParentClass> AssignValue<T>(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
{
dynamic objData = Convert.ChangeType(item, typeof(T));
if (objData != null)
{
//This call would throw exception if CommonProperty is not member of the T Class
objData.CommonProperty = 5;
}
}
return lstParent;
}
如果这不是您想要的情况,请详细说明您面临的问题是什么
创建新界面:
public interface IHasCommonProperty
{
int CommonProperty {get; set;}
}
public class A : ParentClass, IHasCommonProperty
{
public int A_item1;
public string A_item2;
public int CommonProperty {get ; set; }
}
public class B : ParentClass, IHasCommonProperty
{
public int B_item1;
public string B_item2;
public int CommonProperty {get ; set; }
}
private List<ParentClass> AssignValue(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
{
var commonInterface = item as IHasCommonProperty;
if (commonInterface != null)
commonInterface.CommonProperty = 5;
}
return lstParent;
}
您需要做的是让编译器知道您的 classes 是如何布局的。
基本上你必须告诉它,"this T
type, here's what I know about it"。
由于两者之间没有任何共同点,除了两个属性具有相同的名称和类型之外,编译器不会让您轻易地做到这一点。请注意,具有相同名称和类型但属于不同类型的两个属性是不同的属性,您可以将其强制转换为允许您访问它们的通用属性。
除了 dynamic
之外,这里已经有另一个答案,但让我们找到一个更好的方法。
你要做的就是将公共 属性 向下移动到你的公共基础 class:
public class ParentClass
{
public int CommonVariable;
}
public class A : ParentClass
{
public int A_item1;
public string A_item2;
}
public class B : ParentClass
{
public int B_item1;
public string B_item2;
}
然后你必须告诉泛型方法,它将作为 T
给出的所有类型至少是公共基础 class:
private List<ParentClass> AssignValue<T>(List<ParentClass> lstParent)
where T : ParentClass
看到我上面加的那个where T : ParentClass
子句,这告诉编译器每个类型都是那个类型,现在代码可以这样写:
{
foreach (var item in lstParent)
item.CommonVariable = 5;
return lstParent;
}
现在,说了这么多我质疑这个方法的有效性。
就目前而言,您实际上不需要它是通用的。如果将公共域下移到基class,你可以这样写方法:
private List<ParentClass> AssignValue(List<ParentClass> lstParent)
{
foreach (var item in lstParent)
item.CommonVariable = 5;
return lstParent;
}
如果您不能或不愿将公共字段向下移动到基中class,您可以使用另一种方式,使用接口。
首先将字段变成 属性,然后声明一个接口公开此 属性 并在每个 class 上实现 属性,然后让方法,仍然不必是通用的,采用该接口:
public class ParentClass
{
}
public interface ICommon
{
int CommonVariable { get; set; }
}
public class A : ParentClass : ICommon
{
public int A_item1;
public string A_item2;
public int CommonVariable { get; set; }
}
public class B : ParentClass : ICommon
{
public int B_item1;
public string B_item2;
public int CommonVariable { get; set; }
}
private List<ICommon> AssignValue(List<ICommon> lstParent)
{
foreach (var item in lstParent)
item.CommonVariable = 5;
return lstParent;
}