런타임으로 결정된 유형으로 개체 인스턴스화
런타임에 결정될 유형의 개체를 인스턴스화하려는 상황에 있습니다. 또한 해당 유형에 대한 명시 적 캐스트를 수행해야합니다.
이 같은:
static void castTest(myEnum val)
{
//Call a native function that returns a pointer to a structure
IntPtr = someNativeFunction(..params..);
//determine the type of the structure based on the enum value
Type structType = getTypeFromEnum(val);
structType myStruct = (structType)Marshal.PtrToStructure(IntPtr, structType);
}
이것은 분명히 유효한 코드는 아니지만 내가하려는 일의 본질을 전달하기를 바랍니다. 내가 실제로 작업중인 방법은 ~ 35 가지 유형에 대해 마샬링 작업을 수행해야합니다. 동일한 유형 세트로 유사한 작업을 수행해야하는 몇 가지 다른 방법이 있습니다. 따라서이 메서드에서 유형 결정 논리를 분리하여 한 번만 작성하면되고 메서드가 깨끗하고 읽기 쉽게 유지되도록하고 싶습니다.
나는 디자인에 대한 완전한 초보자임을 인정해야한다. 누구든지이 문제에 대한 좋은 접근 방식을 제안 할 수 있습니까? 내가 알지 못하는 적절한 디자인 패턴이있을 수 있다고 생각합니다.
특정 유형의 개체를 즉시 만들 수있는 방법에는 여러 가지가 있습니다.
// determine type here
var type = typeof(MyClass);
// create an object of the type
var obj = (MyClass)Activator.CreateInstance(type);
그리고 obj에서 MyClass의 인스턴스를 얻게됩니다.
또 다른 방법은 반사를 사용하는 것입니다.
// get type information
var type = typeof(MyClass);
// get public constructors
var ctors = type.GetConstructors(BindingFlags.Public);
// invoke the first public constructor with no parameters.
var obj = ctors[0].Invoke(new object[] { });
반환 된 ConstructorInfo 중 하나에서 인수를 사용하여 "Invoke ()"하고 "new"연산자를 사용한 것처럼 클래스의 인스턴스를 반환 할 수 있습니다.
당신은 할 수 있습니다 대부분 이 설명하고 무엇을,하지만 당신은 컴파일시 타입을 알 수 없기 때문에, 당신은 느슨하게 형식의 인스턴스를 유지해야합니다; 사용하는 각 지점에서 유형을 확인하고 적절하게 캐스팅합니다 ( 동역학 을 지원하는 c # 4.0에서는 필요하지 않음 ).
Type type = CustomGetTypeMethod();
var obj = Activator.CreateInstance(type);
...
if(obj is MyCustomType)
{
((MyCustomType)obj).Property1;
}
else if (obj is MyOtherCustomType)
{
((MyOtherCustomType)obj).Property2;
}
Activator.CreateInstance를 찾고 있다고 생각합니다.
다른 사람들이 언급했듯이을 Type
사용 Activator.CreateInstance
하면 결정된 런타임 인스턴스를 쉽게 만들 수 있습니다. 그러나 캐스팅을 Marshal.PtrToStructure
위해 컴파일 타임에 유형을 알려야 하므로 라인 에서 예제 에서처럼 캐스팅 할 수 없습니다. 또한 Activator.CreateInstance
IntPtr과 함께 사용할 수 없습니다.
유형에 공통 기본 클래스 (제외 Object
) 가있는 경우 해당 기본 유형으로 캐스트하고 그에 대한 함수를 호출 할 수 있습니다. 그렇지 않으면 리플렉션을 사용해서 만 함수를 호출 할 수 있습니다.
따라서 다음 중 하나입니다.
static void castTest(myEnum val)
{
//Call a native function that returns a pointer to a structure
IntPtr val = someNativeFunction(..params..);
//determine the type of the structure based on the enum value
Type structType = getTypeFromEnum(val);
BaseClass myStruct = (BaseClass)Marshal.PtrToStructure(IntPtr, structType);
myStruct.SomeFunctionDeclaredInBaseClass();
}
또는:
static void castTest(myEnum val)
{
//Call a native function that returns a pointer to a structure
IntPtr val = someNativeFunction(..params..);
//determine the type of the structure based on the enum value
Type structType = getTypeFromEnum(val);
object myStruct = Marshal.PtrToStructure(IntPtr, structType);
MemberInfo[] function = FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance,
(MemberFilter)delegate(MemberInfo info, object filter)
{
return info.Name == filter.ToString();
}, "SomeFunction");
if (mi.Length > 0 && mi[0] is MethodInfo)
((MethodInfo)mi[0]).Invoke(myStruct, ..params..);
}
동적으로 갈 수 있습니다.
using System;
namespace TypeCaster
{
class Program
{
internal static void Main(string[] args)
{
Parent p = new Parent() { name = "I am the parent", type = "TypeCaster.ChildA" };
dynamic a = Convert.ChangeType(new ChildA(p.name), Type.GetType(p.type));
Console.WriteLine(a.Name);
p.type = "TypeCaster.ChildB";
dynamic b = Convert.ChangeType(new ChildB(p.name), Type.GetType(p.type));
Console.WriteLine(b.Name);
}
}
internal class Parent
{
internal string type { get; set; }
internal string name { get; set; }
internal Parent() { }
}
internal class ChildA : Parent
{
internal ChildA(string name)
{
base.name = name + " in A";
}
public string Name
{
get { return base.name; }
}
}
internal class ChildB : Parent
{
internal ChildB(string name)
{
base.name = name + " in B";
}
public string Name
{
get { return base.name; }
}
}
}
methodName = NwSheet.Cells[rCnt1, cCnt1 - 2].Value2;
Type nameSpace=typeof(ReadExcel);
Type metdType = Type.GetType(nameSpace.Namespace + "." + methodName);
//ConstructorInfo magicConstructor = metdType.GetConstructor(Type.EmptyTypes);
//object magicClassObject = magicConstructor.Invoke(new object[] { });
object magicClassObject = Activator.CreateInstance(metdType);
MethodInfo mthInfo = metdType.GetMethod("fn_"+methodName);
StaticVariable.dtReadData.Clear();
for (iCnt = cCnt1 + 4; iCnt <= ShtRange.Columns.Count; iCnt++)
{
temp = NwSheet.Cells[1, iCnt].Value2;
StaticVariable.dtReadData.Add(temp.Trim(), Convert.ToString(NwSheet.Cells[rCnt1, iCnt].Value2));
}
//if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_AddNum" || Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_SubNum")
//{
// //StaticVariable.intParam1 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 4].Value2);
// //StaticVariable.intParam2 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 5].Value2);
// object[] mParam1 = new object[] { Convert.ToInt32(StaticVariable.dtReadData["InParam1"]), Convert.ToInt32(StaticVariable.dtReadData["InParam2"]) };
// object result = mthInfo.Invoke(this, mParam1);
// StaticVariable.intOutParam1 = Convert.ToInt32(result);
// NwSheet.Cells[rCnt1, cCnt1 + 2].Value2 = Convert.ToString(StaticVariable.intOutParam1) != "" ? Convert.ToString(StaticVariable.intOutParam1) : String.Empty;
//}
//else
//{
object[] mParam = new object[] { };
mthInfo.Invoke(magicClassObject, mParam);
참고 URL : https://stackoverflow.com/questions/981330/instantiate-an-object-with-a-runtime-determined-type
'program tip' 카테고리의 다른 글
정규식 이메일 주소 인식이 어렵습니까? (0) | 2020.12.07 |
---|---|
SQL Server : 테이블 메타 데이터 추출 (설명, 필드 및 해당 데이터 유형) (0) | 2020.12.07 |
Random.Next는 항상 동일한 값을 반환합니다. (0) | 2020.12.07 |
C #에서 SHA1 파일 체크섬을 어떻게 수행합니까? (0) | 2020.12.07 |
git : 시간대 및 타임 스탬프 형식 (0) | 2020.12.07 |